Linq to Entities通过位置映射表自定义排序

时间:2010-04-25 13:55:12

标签: asp.net asp.net-mvc linq entity-framework linq-to-entities

我有一个新闻表,我想实现自定义排序。我之前通过一个具有newsIds和位置的位置映射表完成了这个。

然后我通过选择案例陈述LEFT OUTER JOIN位置表ON news.newsId = position.itemId

CASE WHEN [position] IS NULL THEN 9999 ELSE [position] END

按位置asc,articleDate desc。

排序

现在我正在尝试使用Linq to Entities。我已经设置了具有PK,FK关系的表格,以便我的新闻对象具有实体位置集合。

现在有点我无法解决。如何实现LEFT OUTER JOIN。

我到目前为止:

 var query = SelectMany (n => n.Positions, (n, s) => new { n, s })
                    .OrderBy(x => x.s.position)
                    .ThenByDescending(x => x.n.articleDate)
                    .Select(x => x.n);

这种方式有效。然而,这使用了内部联接,而不是我所追求的。

我有另一个想法:

 ret = ret.OrderBy(n => n.Positions.Select(s => s.position));

但是我收到错误 DbSortClause表达式必须具有可比较的类型。

我也试过

ret = ret.GroupJoin(tse.Positions, n => n.id, s => s.itemId, (n, s) => new { n, s })
                    .OrderBy(x => x.s.Select(z => z.position))
                    .ThenByDescending(x => x.n.articleDate)
                    .Select(x => x.n);

但我得到同样的错误!

如果有人可以帮助我,我将不胜感激!

更新
因此,经过一些游戏后,我设法让它发挥作用。

ret = ret.GroupJoin(entity.Positions, n => n.id, s => s.itemId, (n, s) => new { n, s })
                    .SelectMany(x => x.n.Positions.DefaultIfEmpty(), (n, s) => new { n, s })
                    .OrderBy(x => x.s.position)
                    .ThenByDescending(x => x.n.n.articleDate)
                    .Select(x => x.n.n);

然而,这仍然不完全正确。我无法仅使用特定的positionid或articleType。

如果我有新闻ID 1和评论ID,但在职位表中定义,目前(我认为)linq查询会选择两者吗?

如果我尝试使用where子句,它与内部连接基本相同。我需要的是尝试在选择中使用一个案例,就像我在直接SQL中所做的那样:

CASE WHEN [position] IS NULL OR shuffleId != 1 THEN 9999 ELSE [position] END

我可能要完全重新考虑如何做到这一点。不要以为任何人对替代方法有任何建议吗?

2 个答案:

答案 0 :(得分:2)

怎么样:

var query =
   from n in news
   let p = n.Positions.Select(p=>p.Position).FirstOrDefault() ?? 9999
   orderby p, n.ArticleDate
   select n;

聚苯乙烯。以上假设每个新闻只有1个位置条目...如果不是这样的话,那就好像很奇怪。


OP在以下评论中发布的解决方案:

ret = ret
      .GroupJoin(tse.Positions, n => n.id, s => s.itemId, (n, s) => new { n, s }) 
      .SelectMany(x => x.s.DefaultIfEmpty(), (n, s) => new { n, s }) 
      .OrderBy(x => x.s.position == null || x.s.positionId != positionId ? 9999 : x.s.position) 
      .ThenByDescending(x => x.n.n.articleDate) 
      .Select(x => x.n.n);

答案 1 :(得分:1)

我只能建议您使用一些存储过程方法 - 通过新的Linq-To-SQL类将其添加到您的解决方案中,然后使用DataContext来获取它的结果。在这种情况下,您不会将查询用于数据库,这对您的解决方案很有用。

唯一的问题是此过程的结果类型可能与您的新闻类不兼容 可能你必须编写一些代码来将一个表示转换为另一个表示。

如果需要,我可以为我的解决方法提供一些插图。