3

我最近需要对相互关联的页面和导航菜单条目列表进行排序。

每个Navigation人都有一个Page财产。每个Page人都有一个Navigation财产。它们是我数据库中的外键引用。

我有一个Navigation项目列表以及每个Page项目的列表。问题在于,无论 aPage是否与 a 关联Navigation,它都存储在Page项目列表中。

我想生成一个排序的Page项目列表,如下所示:具有非空值Navigation的项目按Page.Navigation.Index属性排序。具有 nullNavigation的项目按Page.Title属性排序,然后按Page.ID属性排序。

以下是我们目前所做的,它在大多数情况下都有效,但有一些例外。我遇到的问题是它不处理没有关联导航的页面的重复标题。

List<Page> page1 = db.Navigations.OrderBy(n => n.Index).Select(n => n.Page).ToList();

List<Page> page2 = db.Pages.Where(p => !db.Navigations.Contains(p.Navigation)).ToList();

model.Pages = page1.Concat(page2).ToList();

这是一些示例数据和预期结果

Pages Table (PageID, Title, Content)
0, "Home", "<html>This is a home page</html>"
3, "Some Page", "<html>This is some page.</html>"
2, "Some hidden page", "<html>This is some hidden page.</html>"
4, "Products", "<html>We've got products!</html>"
5, "aaaaa", "<html>This should be sorted to the top of pages with no nav</html>"

Navigations Table (PageID, Index)
0, 0
3, 2
4, 1

Output (PageID, Title, Content)
0, "Home", "<html>This is a home page</html>"
4, "Products", "<html>We've got products!</html>"
3, "Some Page", "<html>This is some page</html>"
5, "aaaaa", "<html>This should be sorted to the top of pages with no nav</html>"
2, "Some hidden page", "<html>This is some hidden page.</html"

我很好奇这是否可以以更好看的方式以及查询语法而不是过程语法来完成。

4

1 回答 1

3

我想这会解决这个问题:

model.Pages = db.Pages
  .OrderBy(p=>p.Navigation != null ? p.Navigation.Index : Int32.MaxValue)
  .ThenBy (p=>p.Title)
  .ThenBy (p=>p.PageID)
  .ToList();

或者如果你喜欢这种语法

var query = from p in db.Pages
            orderby p.Navigation != null ? p.Navigation.Index : Int32.MaxValue,
                       p.Title, 
                       p.PageID
            select p;

model.Pages = query.ToList();

当存在时,这些页面按 Navigation.Index 排序,没有 Navigation.Index 的页面将出现在这些页面之后(它们实际上将 Int32.MaxValue 作为 Navigation.Index)。因为没有 Navigation.Index 的那些现在具有唯一值 (Int32.MaxValue),所以这些值再次按 Title 排序,然后按 PageId。

于 2012-04-20T08:55:34.173 回答