使用一列对Linq列表进行排序

时间:2011-08-18 21:21:35

标签: c# linq sorting telerik-open-access

我想它应该很简单,但我找不到怎么做。 我有一个linq查询,它选择一个int类型的列,我需要它排序。

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。 谁能说一些对此有用的东西?

4 个答案:

答案 0 :(得分: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语句中。 我们已经开始致力于改善这种行为。 谢谢你指出这一点。

此致

拉​​尔夫

答案 1 :(得分:2)

与我的其他问题相同的答案,事实证明我正在使用的Linq提供程序,Telerik OpenAccess ORM附带的提供程序与标准的Linq to SQL提供程序有所不同!请参阅我在帖子中发布的SQL!我完全不期待这样的事情,但我似乎Telerik OpenAccess仍需要很多改进。所以在开始使用它之前要小心。它看起来不错,但它有一些严重的缺点。

答案 2 :(得分:1)

我无法复制这个问题。但是只要确保在检查集合时枚举集合。你是如何检查结果的?

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

请记住,这不会改变数据库中或其他任何地方的记录顺序 - 只能从values枚举中检索它们的顺序。

答案 3 :(得分:-2)

由于您的values变量是Linq表达式的结果,因此在您调用ToListToArray之类的方法之前,它确实没有值,等

回到您的示例,x方法中的变量OrderBy将被视为p.SearchColumn3,因此,它是一个字符串。

为避免这种情况,您需要在p.SearchColumn3方法之前让OrderBy变为整数。 您应该在代码中添加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);

另外,你可以将order by语句与第一个结合起来,没关系。