2010-04-25 26 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獲取結果。在這種情況下,您不會將查詢用於數據庫,這對您的解決方案非常有用。

唯一的問題是此過程的結果類型可能與您的新聞類不兼容 也許您將不得不編寫一些代碼將一個表示法轉換爲另一個表示法。

如果需要,我可以爲我的解決方法提供一些插圖。