2012-04-20 36 views
3

我最近需要对页面和导航菜单项的列表进行排序,每个页面和导航菜单项都与另一个相关联。使用LINQ在多个表中按多个属性条件排序元素

每个Navigation有一个Page属性。每个Page都有一个Navigation属性。他们是我的数据库中的外键引用。

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

我想产生的Page项目,像这样一个排序列表:项目与非空NavigationPage.Navigation.Index属性进行排序。带有空Navigation的项目按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" 

我很好奇,如果这是可能的一个更好看的方式做的,也是在查询语法,而不是程序的语法。

+0

请问您可以发布一些示例数据和您期待的结果吗? – 2012-04-20 08:24:23

+0

@WouterdeKort有一些示例数据。本质上,它是按照索引为具有导航关联的页面定购的。这是标题,最后是那些没有导航关联的“PageID”。 – 2012-04-20 08:45:47

+0

@Michael:页面最多只能有一个“导航”?如果是这样,为什么不只是把'索引'字段放在页表中...? – 2012-04-20 08:54:21

回答

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有序当这存在,没有导航的人。索引会出现在这些之后(他们实际上将Int32.MaxValue作为Navigation.Index)。因为没有Navigation.Index的人现在有一个唯一的值(Int32.MaxValue),所以这些由Title再次由PageId进行排序。

+1

我有一些非常接近的东西,除非我试图用三元语句或奇怪的东西做一个连接。这使得更有意义。我想这就是你对复杂事物的理解。它完美的作品。 – 2012-04-20 09:14:17