2010-04-25 25 views
3

我有一个新闻表,我想实现自定义排序。我之前通过具有newsIds和位置的位置映射表完成了此操作。Linq到实体定制通过位置映射表订购

我然后LEFT OUTER JOIN ON news.newsId = position.itemId位置表以选择case语句

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

和顺序通过位置递增,articleDate递减。

现在我正在尝试对Linq执行相同的实体。我已经建立了PK,FK关系的表格,这样我的News对象就有了一个Entity Collection的职位。

现在来了我无法解决的问题。如何实现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); 

这还挺工作。但是,这使用INNER JOIN,所以不是我所追求的。

我有另一个想法:

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); 

,但我得到了同样的错误!

如果有人能帮助我,那将是非常感谢!

UPDATE:
所以我大概打了一些后设法得到它的工作。

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

如何:

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); 
+0

谢谢!它仍然不完美,但我认为我的工作你的答案成为一个可用的答案。 – 2010-05-05 08:22:06

+1

只是为了参考,这是我终于如何解决它! 这可能有点难以阅读,所以复制/粘贴是你的朋友!: ret = ret.GroupJoin(tse.Positions,n => n.id,s => s.itemId,(n,s (x => xsDefaultIfEmpty(),(n,s)=> new {n,s}) .OrderBy(x => xsposition == null ||) xspositionId!= positionId?9999:xsposition) 。ThenByDescending(x => xnnarticleDate) .Select(x => xnn); – 2010-05-25 20:50:32

1

我可以建议你在使用一些存储过程的方法 - 把它添加到您的解决方案通过新的LINQ到SQL类,然后使用DataContext获取结果。在这种情况下,您不会将查询用于数据库,这对您的解决方案非常有用。

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

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