c# - 使用 LINQ 按多个表中的多个属性有条件地对元素进行排序

标签 c# .net linq sql-order-by

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

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

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

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

以下是我们目前所做的,大部分情况下都有效,但也有少数异常(exception)。 我遇到的问题是它不处理没有关联导航的页面的重复标题。

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"

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

最佳答案

我猜这会解决问题:

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 排序,没有 Navigation.Index 的页面将出现在这些页面之后(它们实际上将 Int32.MaxValue 作为 Navigation.Index)。因为没有 Navigation.Index 的那些现在有一个唯一值 (Int32.MaxValue),所以这些将再次按 Title 然后按 PageId 排序。

关于c# - 使用 LINQ 按多个表中的多个属性有条件地对元素进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10240658/

相关文章:

c# - 在 C# 中获取动态类型的最大值

c# - SelectedIndexChanges 在 TextChanged 事件之前触发

c# - 错误信息 "Operator ' .' cannot be applied to operand of type ' lambda expression '"when converting a method to Extension Method?

.net - 集合的xml序列化

c# - 艰难的 Linq 查询

c# - 使用 UserProfileManager 获取随机用户

c# - Twitterizer - 搜索 API 示例

c# - API 调用的 JSON 返回类型

visual-studio-2010 - 需要在 Visual Studio 2010 中调试 LINQ 简单查询

c# - LINQ 计算出现次数