How do I correctly use EF4 Navigation Properties?
M

1

0

I've created a database using the EF4 model-first approach. In my model, there's an N-to-M relationship between two entities:

enter image description here

I've filled my database with some dummy data, including 3 records of type Diagnosis and 3 records of type TreatmentSchema and associations between them. Here's the code snippet I used to do this:

using(var container = new SmartTherapyContainer()) {
  var diagnosisA = new Diagnosis() { Id = Guid.NewGuid(), Name = "Diagnosis A" };
  var diagnosisB = new Diagnosis() { Id = Guid.NewGuid(), Name = "Diagnosis B" };
  var diagnosisC = new Diagnosis() { Id = Guid.NewGuid(), Name = "Diagnosis C" };
  container.Diagnoses.AddObject(diagnosisA);
  container.Diagnoses.AddObject(diagnosisB);
  container.Diagnoses.AddObject(diagnosisC);

  var schemaA = new TreatmentSchema() { Id = Guid.NewGuid(), Name = "Schema 1" };
  var schemaB = new TreatmentSchema() { Id = Guid.NewGuid(), Name = "Schema 1" };
  var schemaC = new TreatmentSchema() { Id = Guid.NewGuid(), Name = "Schema 1" };
  container.Schemas.AddObject(diagnosisA);
  container.Schemas.AddObject(diagnosisB);
  container.Schemas.AddObject(diagnosisC);

  diagnosisB.TreatmentSchemas.Add(schemaA);
  diagnosisC.TreatmentSchemas.Add(schemaA);
  diagnosisC.TreatmentSchemas.Add(schemaB);
  diagnosisC.TreatmentSchemas.Add(schemaC);

  container.SaveChanges();
}

I verified that the associations are indeed stored in the reference table created through EF4's mapping. However, when I retrieve a Diagnosis via the container.Diagnoses collection later, its .TreatmentSchemas collection is always empty.

I tried debugging into the EF4-generated code and all it does is lazily create said collection, but it doesn't fill it with the associated objects. Ayende's Entity Framework Profiler shows no queries being generated at all when the property is accessed, which leads me to believe that I'm doing something wrong here.

How can I get a list of the associated TreatmentSchemas?

Mama answered 19/3, 2011 at 15:11 Comment(1)
In case it's relevant, I'm using the "Self-Tracking Entity Generator" to generate the code for my EF4 model.Mama
R
2

Navigation properties are not loaded by default. You must use either eager loading or lazy loading but because you are using self tracking entities your choice is only eager loading because STEs don't support lazy loading. So if you want to get Diagonstic instance with all related TreatmentSchemas you must call:

var diagnosis = context.Diagnoses.Include("TreatmentSchemas").FirstOrDefault();
Renoir answered 19/3, 2011 at 16:2 Comment(2)
Thank you! Referring to the table name down in a string is a bit refactoring-unfriendly, maybe I can work around this by adding an explicit method to my service. It's good to know this limitation, that would have cost me some headache later on :)Mama
If you don't like using Include with the navigation property name chech EF 4.1 because it has strongly typed version with lambdas.Renoir

© 2022 - 2024 — McMap. All rights reserved.