Now that we have built our main entity skeleton, we need to create some relationships between them. We want to be able to do stuff like retrieve a Quiz, then browse to their related Questions and get the available Answers. We'll also need to fetch the Result(s) for any given score, find out the ApplicationUser who made the quiz, and so on. To do this, we have to implement a set of entity-related properties that Entity Framework will load on demand using its default Lazy-Load retrieval feature.
The first thing we’ll do is add a new region to our Quiz class containing these three new properties:
#region Lazy-Load Properties
/// <summary>
/// The quiz author: it will be loaded
/// on first use thanks to the EF Lazy-Loading feature.
/// </summary>
[ForeignKey("UserId")]
public virtual ApplicationUser User { get; set; }
/// <summary>
/// A list containing all the questions related to this quiz.
/// It will be populaed on first use thanks to the EF Lazy-Loading feature.
/// </summary>
public virtual List<Question> Questions { get; set; }
/// <summary>
/// A list containing all the results related to this quiz.
/// It will be populaed on first use thanks to the EF Lazy-Loading feature.
/// </summary>
public virtual List<Result> Results { get; set; }
#endregion
Whoever has some experience with Entity Framework won’t miss the ForeignKey Data Annotation; this is one of the many Code-First configuration overrides we’ll need to use to have our Data Model properly built. There’s nothing complex here, we’re just telling EF that this property should be loaded using the UserId property defined earlier; this will also create a one-to-many binding relationship (also known as constraint), as long as our chosen Database will support the feature.
Let's do the same with the other entities, starting with the Question:
#region Lazy-Load Properties
/// <summary>
/// The parent quiz.
/// </summary>
[ForeignKey("QuizId")]
public virtual Quiz Quiz { get; set; }
/// <summary>
/// A list containing all the answer related to this question.
/// </summary>
public virtual List<Answer> Answers { get; set; }
#endregion
Then, move on to the Answer:
#region Lazy-Load Properties
/// <summary>
/// The parent question.
/// </summary>
[ForeignKey("QuestionId")]
public virtual Question Question { get; set; }
#endregion
Continue with the Result:
#region Lazy-Load Properties
/// <summary>
/// The parent quiz.
/// </summary>
[ForeignKey("QuizId")]
public virtual Quiz Quiz { get; set; }
#endregion
Now, conclude with the ApplicationUser:
#region Lazy-Load Properties
/// <summary>
/// A list of all the quiz created by this users.
/// </summary>
public virtual List<Quiz> Quizzes { get; set; }
#endregion
That's it. As we can see, for each Quiz, we want to retrieve the owner user and all the questions and results; for each Question, we want the parent quiz and all the answers; for each Answer, the parent question; for each Result, the parent quiz; last but not least, for each ApplicationUser, the list of quizzes that they created.