Many of the bugs I've been fixing lately are a result of null references when accessing navigation properties of objects loaded using entity framework. I believe there must be a flaw in how I'm designing my methods. Here's an example...
A Task contains Many Roles, each Role references a User.
public class Role
{
public int Id;
public int User_Id;
public string Type;
}
public class User
{
public int Id
public string Name;
}
public class Task
{
public int Id;
public string Name;
public string Status;
public List<Role> Roles;
}
Considering that I would have queried my context like this by mistake and not loaded User...
var task = context.Tasks.Include(x=>x.Roles).FirstOrDefault;
And then I call this method...
public void PrintTask(Task task)
{
Console.WriteLine(task.Name);
Console.WriteLine(task.Status);
foreach(var r in task.Roles)
{
Console.WriteLine(r.User.Name); //This will throw NRE because User wasn't loaded
}
}
I may have built this method with every intention to load Roles and User but next time I use it I may forget that I need both. Ideally the method definition should tell me what data is necessary, but even if I pass in both Task and Roles, I'm still missing Roles->User.
What's the proper way to reference these relationships and be sure that they're loaded in something like this print method? I'm interested in a better design, so "Use Lazy Loading" isn't the answer I'm looking for.
Thanks!
EDIT:
I know I can load the task like this...
var task = context.Tasks.Include(x=>x.Roles.Select(z=>z.User)).FirstOrDefault();
What I want to know is how do I design my method so that when I come back and use it 6 months from now I know what data needs to be loaded in my entities? The method definition doesn't indicate what is necessary to use it. Or how to I block against these NullReferences. There has to be a better design.