Ho un progetto MVC e un modello EF6.
LazyLoading è abilitato. Nel controller ho la seguente azione
public ActionResult AddStage(int projectId, int employeeId)
{
using(var context = new TestProjectEntities())
{
var project = context.Projects.Find(projectId);
if (project != null)
{
var stage = new Stage() {EmployeeID = employeeId, StageType = 1};
project.Stages.Add(stage);
context.Stages.Add(stage);
context.SaveChanges();
}
ListEmployees(project);
}
return Redirect("Index");
}
private void ListEmployees(Project project)
{
var names = new List<string>();
foreach(var stage in project.Stages)
{
if (stage.Employee != null)
{
names.Add(stage.Employee.Name);
}
}
}
Ma nel metodo ListEmployees stage.Employee == null nell'istruzione foreach. Perché?
E se chiamo AddStage per la seconda volta poi stage.Employee! = Null in ListEmployee
Questo perché stai semplicemente impostando la proprietà di chiave Stage.EmployeeID
( Stage.EmployeeID
) senza impostare la proprietà di navigazione ( Stage.Employee
).
Di solito, dopo aver chiamato SaveChanges()
, EF aggiorna anche la proprietà di navigazione. Tuttavia, poiché l'oggetto Stage
viene creato manualmente da te, non viene tracciato (utilizzando un DynamicProxy) e dovrai risolvere esplicitamente la relazione:
context.Entry(stage).Reference(c => c.Employee).Load();
Un altro approccio sarebbe quello di recuperare il Employee
e utilizzarlo invece di impostare la proprietà di chiave esterna:
var employee = context.Employees.Find(employeeId);
var stage = new Stage() { Employee = employee, StageType = 1};
Vedi MSDN
new Stage()
Non farlo con oggetti EF. Non si otterrà l'oggetto proxy corretto che può caricare le proprietà di navigazione lazy. Devi usare qualcosa come dbContext.Set<Stage>().Create()