我想它应该很简单,但我找不到怎么做。 我有一个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。 谁能说一些对此有用的东西?
答案 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
表达式的结果,因此在您调用ToList
,ToArray
之类的方法之前,它确实没有值,等
回到您的示例,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语句与第一个结合起来,没关系。