Reputation: 27
I'm working on a project where I need to create a hierarchical page structure in a database, and retrieve the pages like mydomain.com/firstpage/secondpage/thirdpage etc.
I have the following, stripped down, model:
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid PageId { get; set; }
public string Name { get; set; }
public string Url { get; set; }
public Guid? ParentId { get; set; }
[ForeignKey("ParentId")]
public virtual Page Parent { get; set; }
public virtual ICollection<Page> Children { get; set; }
Then I have a function to lookup the PageId, as follows:
private Guid GetPageByUrl(string slug)
{
var pages = pageService.GetPages();
var urlArray = slug.Split('/');
var page = new Page();
switch (urlArray.Count())
{
case 1:
page = pages.Where(p => p.Url == urlArray[0]
&& p.ParentId == null)
.FirstOrDefault();
break;
case 2:
page = pages.Where(p => p.Url == urlArray[1]
&& p.Parent.Url == urlArray[0]
&& p.Parent.ParentId == null)
.FirstOrDefault();
break;
case 3:
page = pages.Where(p => p.Url == urlArray[2]
&& p.Parent.Url == urlArray[1]
&& p.Parent.Parent.Url == urlArray[0]
&& p.Parent.Parent.ParentId == null)
.FirstOrDefault();
break;
case 4:
page = pages.Where(p => p.Url == urlArray[3]
&& p.Parent.Url == urlArray[2]
&& p.Parent.Parent.Url == urlArray[1]
&& p.Parent.Parent.Parent.Url == urlArray[0]
&& p.Parent.Parent.Parent.ParentId == null)
.FirstOrDefault();
break;
}
return page.PageId;
}
Is there any better way to do this?
Since now I have to define how to lookup the URLs by my switch-statement.
Upvotes: 0
Views: 226
Reputation: 35531
You can make a loop to build the query from the root end:
var pageQuery = pageService.GetPages();
foreach( Int32 i = 0; i < urlArray.Count(); i++){
var url = urlArray[i];
if (i == 0) // first url must match root page
pageQuery = pageQuery.Where(p => p.ParentId == null);
else // next urls must match next level children
pageQuery = pageQuery.SelectMany(p => p.Children);
pageQuery = pageQuery.Where(p => p.Url == url);
}
return pageQuery.FirstOrDefault();
Upvotes: 1