I'm trying to figure out the best way to handle loading objects with different graphs (related entities) depending on the context their being used.
For example Here's a sample of my domain objects:
public class Puzzle
{
public Id{ get; private set; }
public string TopicUrl { get; set; }
public string EndTopic { get; set; }
public IEnumerable<Solution> Solutions { get; set; }
public IEnumerable<Vote> Votes { get; set; }
public int SolutionCount { get; set; }
public User User { get; set; }
}
public class Solution
{
public int Id { get; private set; }
public IEnumerable<Step> Steps { get; set; }
public int UserId { get; set; }
}
public class Step
{
public Id { get; set; }
public string Url { get; set; }
}
public class Vote
{
public id Id { get; set; }
public int UserId { get; set; }
public int VoteType { get; set; }
}
What I'm trying to understand is how to load this information differently depending on how I'm using it.
For example, on the front page I have a list of all puzzles. At this point I don't really care about the solutions for the puzzle or for the steps in those solutions (which can get pretty hefty). All I want are the puzzles. I would load them from my controller like this:
public ActionResult Index(/* parameters */)
{
...
var puzzles = _puzzleService.GetPuzzles();
return View(puzzles);
}
Later on for the puzzle view I now care about only the solutions for the current user. I don't want to load the entire graph with all of the solutions and all of the steps.
public ActionResult Display(int puzzleId)
{
var puzzle = _accountService.GetPuzzleById(puzzleId);
//I want to be able to access my solutions, steps, and votes. just for the current user.
}
Inside my IPuzzleService, my methods look like this:
public IEnumerable<Puzzle> GetPuzzles()
{
using(_repository.OpenSession())
{
_repository.All<Puzzle>().ToList();
}
}
public Puzzle GetPuzzleById(int puzzleId)
{
using(_repository.OpenSession())
{
_repository.All<Puzzle>().Where(x => x.Id == puzzleId).SingleOrDefault();
}
}
Lazy loading doesn't really work in the real world, because my session is being disposed right after each unit of work. My controllers don't have any concept of the repository and therefore do not manage session state and can't hold on to it until the view is rendered.
I'm trying to figure out what the right pattern to use here is. Do I have different overloads on my service like GetPuzzleWithSolutionsAndVotes
or more view specific like GetPuzzlesForDisplayView
and GetPuzzlesForListView
?
Am I making sense? Am I way off base? Please help.