2013-04-04 60 views
4

我需要一些幫助創建一個LINQ選擇,我有一個表中有一些列,但只有2這個問題的興趣。需要幫助創建一個LINQ選擇

userid, type 

現在這個表有幾千項,我只想要頂部,讓我們說50到目前爲止好,但最困難的部分是,有成功的一個很多行只應是計爲1 例

Type UserId 
============ 
Add 1 
Add 1 
Add 1 
Add 2 

我想這行我取出的限制只能算作2,但我想仍有待被輸出的所有的行。 這是可能的一個單一的SQL請求,或者我應該找到另一種方式來做到這一點?

編輯:我可以添加列到表中,如果這可以解決問題的值。 EDIT2:Sotred程序也是一種溶液

實施例2:此應該算作3行

Type UserId 
============ 
Add 1 
Add 1 
Add 2 
Add 1 
+2

我覺得這很難。 Linq和SQL擅長設置操作,而不是順序處理。經典的'foreach'更適合這裏。 – 2013-04-04 21:47:12

+0

是的,但我不想從數據庫中獲取更多的需要,理論上可以在那裏有多於1000行的序列 – Androme 2013-04-04 21:48:51

+0

我看到一個存儲過程迫在眉睫... – 2013-04-04 21:50:32

回答

1

你堅持使用LINQ嗎?

添加一個PK身份。
按PK排序。
使用DataReader並只計算更改。
然後,只要停止當更改計數是在您的最大值。

如果你不在.NET環境中,那麼與光標相同的東西。

由於LINQ被推遲,你可能只能在LINQ中訂購,然後在ForEach上退出。

+0

我想堅持我的存儲庫,但這將適當地成爲最好的解決方案。 – Androme 2013-04-04 23:02:14

+0

查看我的答案更新 – Paparazzi 2013-04-05 14:13:24

1

我不是接近計算機現在所以我不知道是100%正確的語法明智的,但我相信你正在尋找的東西是這樣的:

data.Select(x => new {x.Type, x.UserId}) 
    .GroupBy(x => x.UserId) 
    .Take(50); 
+0

我還沒有真正與groupby合作過很長一段時間,但是我記得它會將所有條目分組爲1條單條目嗎? – Androme 2013-04-04 21:35:19

+0

你是對的,我沒有注意到其他條件,它應該只分組相鄰,我會給它更多的思考解決方案,並回來編輯。 – 2013-04-04 22:58:02

1

可能使用LINQ做到這一點,但它可能是很多比傳統for循環慢。一種方法是:

data.Where((s, i) => i == 0 || 
        !(s.Type == data[i-1].Type && s.UserId == data[i-1].UserId)) 

這將跳過任何「重複」項目具有相同類型和用戶標識與「上一個」項目。

但是,只有data有一個索引器(一個數組或者實現了IList的東西)才能工作。 IEnumerableIQueryable將不起作用。另外,它幾乎肯定不會被SQL翻譯,因此您必須將所有結果都提取出來並過濾內存。

如果你想在SQL中完成它,我會嘗試掃描遊標並填充臨時表,如果其中一個值發生變化或使用包含ROW_NUMBER列的公用表表達式,查詢類似的LINQ上述方法:

WITH base AS 
(
SELECT 
    Type, 
    UserId, 
    ROW_NUMBER() OVER (ORDER BY ???) AS RowNum 
    FROM Table 
) 
SELECT b1.Type, b1.UserId 
FROM base b1 
LEFT JOIN base b2 ON b1.RowNum = b2.RowNum - 1 
WHERE (b1.Type <> b2.Type OR b1.UserId <> b2.UserId) 
ORDER BY b1.RowNum 
+0

這就是我想要避免的,理論上這張桌子可能會有更多的上千個條目! – Androme 2013-04-04 22:02:49

+0

嗯,我不能你所做的工作的SQL,但如果我正確地讀它劑量它不僅返回不同的值? – Androme 2013-04-04 22:24:30

+0

它應該返回與下一行不同的任何行。最後一行應該被包含,因爲那個時候'b2'值將是NULL。你是否收到錯誤或者錯誤的結果? – 2013-04-04 22:28:06

1

你可以用LINQ做到這一點,但我認爲這可能是更容易去了「(每個)循環」路線......

data.Select((x, i) => new { x.Type, x.UserId, i }) 
    .GroupBy(x => x.Type) 
    .Select(g => new 
    { 
     Type = g.Key, 
     Items = g 
      .Select((x, j) => new { x.UserId, i = x.i - j }) 
    }) 
    .SelectMany(g => g.Select(x => new { g.Type, x.UserId, x.i })) 
    .GroupBy(x => new { x.Type, x.i }) 
    .Take(50); 
    .SelectMany(g => g.Select(x => new { x.Type, x.UserId }));