2011-08-18 64 views
2

我想應該很簡單,但我找不到如何去做。 我有一個linq查詢,選擇一個int類型的列,我需要它排序。用一列對Linq列表進行排序

var values = (from p in context.Products 
       where p.LockedSince == null 
       select Convert.ToInt32(p.SearchColumn3)).Distinct(); 
values = values.OrderBy(x => x); 

SearchColumn3是op類型的字符串,但我只包含整數。所以我想,轉換到Int32和訂購肯定會給我一個很好的1,2,3排序的值列表。但相反,列表保持有序,就像是字符串一樣。

199 20 201 

更新: 我已經做了一些測試,與C#代碼和LinqPad。 LinqPad生成以下SQL:

SELECT [t2].[value] 
FROM (
    SELECT DISTINCT [t1].[value] 
    FROM (
     SELECT CONVERT(Int,[t0].[SearchColumn3]) AS [value], [t0].[LockedSince], [t0].[SearchColumn3] 
     FROM [Product] AS [t0] 
     ) AS [t1] 
    WHERE ([t1].[LockedSince] IS NULL) 
    ) AS [t2] 
ORDER BY [t2].[value] 

我的SQL事件探查說,我的C#代碼生成這一塊的SQL:

SELECT DISTINCT a.[SearchColumn3] AS COL1     
FROM [Product] a 
WHERE a.[LockedSince] IS NULL 
ORDER BY a.[SearchColumn3] 

所以它看起來像C#的LINQ代碼只是省略了Convert.ToInt32。 任何人都可以說一些有用的東西嗎?

+0

是否有錯字?...你是排序'diameters'可變但選擇到'values'變量。它應該讀取'diameters = values.OrderBy(x => x);'? –

+0

也許是因爲你正在分揀'直徑'而不是'價值'? –

+0

您正在選擇「值」,但訂購了「直徑」。這只是一個複製編輯問題,或者它是你的實際代碼? – ChrisF

回答

2

與我的其他問題相同的答案,事實證明,我正在使用的Linq提供程序,Telerik OpenAccess ORM附帶的提供程序與標準的Linq to SQL提供程序不同。查看我在開篇文章中發佈的SQL!我完全不期待這樣的事情,但我似乎Telerik OpenAccess的事情仍然需要很多改進。所以在開始使用之前要小心。它看起來不錯,但它有一些嚴重的缺點。

-2

因爲你values變量是Linq表達的結果,因此,它行的事不是真的有值,直到你調用一個方法,如ToListToArray

回到你的例子,變量xOrderBy方法中,將被視爲p.SearchColumn3,因此它是一個字符串。

要避免這種情況,您需要讓p.SearchColumn3OrderBy方法之前變爲整數。 你應該在你的代碼添加let聲明如下:

var values = (from p in context.Products 
       where p.LockedSince == null 
       let val = Convert.ToInt32(p.SearchColumn3) 
       select val).Distinct(); 
values = values.OrderBy(x => x); 

此外,您可以通過聲明與第一組合順序,將被罰款。

+2

-1'values'變量只包含'Int32'類型 - 它不包含字符串。您的建議代碼與OP代碼沒有任何區別。 –

0

我無法複製此問題。但是,只要確保在檢查它時列舉收集。你如何檢查結果?

values = values.OrderBy(x => x); 
foreach (var v in values) 
{ 
    Console.WriteLine(v.ToString()); 
} 

請記住,這不會在數據庫或任何其他地方更改的記錄的順序 - 只爲了你可以從values枚舉檢索。

3

[免責聲明 - 我在Telerik的工作]

就可以解決這個問題Telerik的OpenAccess的ORM了。這是我在這種情況下建議的。

var values = (from p in context.Products 
       where p.LockedSince == null 
       orderby "cast({0} as integer)".SQL<int>(p.SearchColumn3) 
       select "cast({0} as integer)".SQL<int>(p.SearchColumn3)).ToList().Distinct(); 

的OpenAccess提供了SQL擴展方法,它給你添加一些特定的SQL代碼來生成的SQL語句的能力。 我們已經開始致力於改善這種行爲。 謝謝你指出這一點。

問候

拉爾夫