2011-08-18 42 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语句的能力。 我们已经开始致力于改善这种行为。 谢谢你指出这一点。

问候

拉尔夫