Question

Currently I have an Model that's recursive (one of its properties is of the same type).

For example:

public class Page
{
  public int ID { get; set; }
  public string Description{ get; set; }
  public int ParentID  {get; set; }

}

Now, when I want to access someone's parent, I will have to get the ParentID, query the database and find the Page. What I want is that I can do the following:

Page page = _db.GetFirstPage();
Page pagesParent = page.Parent;

How can I achieve that? I've tried the following:

public class Page
{
  public int ID { get; set; }
  public string Description{ get; set; }
  public int ParentID  {get; set; }
  public Page Parent { get; set; }

}

Because I thought the entity framework would automagically assume Parent is linked to parentID, but that doesn't work.


Alright here is all my code: The controller method is as follows:

public ActionResult Create()
    {
        var pages = _db.Pages;
        ViewBag.Pages = new SelectList(pages,"ID","Description");
        return View();
    }

In the view:

    <div class="editor-label">
        @Html.LabelFor(model => model.ParentID)
    </div>
    <div class="editor-field">
        @Html.DropDownList("Pages", String.Empty)
        @Html.ValidationMessageFor(model => model.ParentID)
    </div>

The model:

    public int ID { get; set; }
    public string Description { get; set; }
    public string Body { get; set; }

    public int? ParentID { get; set; }
    public virtual Page Parent { get; set; }

When I go to the Create View. I get a list of all the Pages, but when I create them, the new Page's Parent property is null.

Was it helpful?

Solution

You need to make ParentID property nullable because every page will not have a parent. Also make Parent property virtual to allow lazy loading.

public class Page
{
  public int ID { get; set; }
  public string Description{ get; set; }

  public int? ParentID  {get; set; }
  public virtual Page Parent { get; set; }

}

OTHER TIPS

EF of course can handle recursive association and also can automagically look up associations for you. So this code is ok:

public class Page
{
  public int ID { get; set; }
  public string Description{ get; set; }
  public int ParentID  {get; set; }
  public Page Parent { get; set; }

}

Your problem is the EF does not automatically load relations if your are not using lazy loading. You have two options:

  • Turn on lazy loading for the Parent property as making the property virtual ( in this case EF can override it to do the the loding
  • Explicitly tell EF with the Include method to when you request a Page also load the associated Parent objects. So your GetFirstPage() method should contain something like this:

    efContext.Pages.Include(p => p.Parent).First();
    
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top