2012-05-22 3 views
0

Я работаю над проектом, где мне нужно, чтобы создать иерархическую структуру страницы в базе данных, и восстановить страницы, как mydomain.com/firstpage/secondpage/thirdpage и т.д.Entity Framework - Динамический рекурсивный поиск по URL

у меня есть следующий, урезанная, модель:

[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; } 

Тогда у меня есть функции для поиска в PageId следующим образом:

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; 
} 

есть ли лучший способ сделать это?

С этого момента я должен определить, как искать URL-адреса с помощью моего оператора switch.

ответ

1

Вы можете сделать петлю для построения запроса из корневого конца:

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(); 
+0

Спасибо! Это намного лучше, чем мой предыдущий жесткий код :) – Fredrik

Смежные вопросы