实体框架 - URL的动态递归查找

时间:2012-05-22 13:24:38

标签: asp.net-mvc-3 entity-framework-4

我正在开发一个项目,我需要在数据库中创建分层页面结构,并检索mydomain.com/firstpage/secondpage/thirdpage等页面。

我有以下,剥离,模型:

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

有没有更好的方法呢?

从现在起,我必须定义如何通过switch-statement查找URL。

1 个答案:

答案 0 :(得分: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();