EF 6在sql端使用Convert(Cast)进行自然排序

时间:2017-03-01 10:26:12

标签: c# sql-server entity-framework linq

我有以下问题,我的数据库varchar中的一列,它由字母和数字组成,问题是我希望结果自然排序。

所以1,2 .. 10, 11

目前我正在1,10,11,..,2

在SQL端,可以使用以下查询

完成此操作
SELECT [ID]
  ,[ChangedAt]
  ,[ChangedBy]
  ,[CreatedAt]
  ,[CreatedBy]
  ,[RowVersion]
  ,[Name]
  ,[ERPID]
  ,[IsERPSynchronised]
  ,[Code]
FROM [Departments] order by
CASE ISNUMERIC(Code + 'e0') WHEN 1 THEN 0 ELSE 1 END, -- letters after numbers
CASE ISNUMERIC(Code + 'e0') WHEN 1 THEN CAST(Code AS INT) ELSE 0 END,
Code

大致会转换为以下linq查询

IQueryable<Department> query = db.Departments;    
query = query.OrderBy(item => SqlFunctions.IsNumeric(item.Code) == 1 ? 0 : 1)
.ThenBy(item => SqlFunctions.IsNumeric(item.Code) == 1 ? Convert.ToDouble(item.Code) : 0);
return query.ToList();

除此之外抛出一个错误,即Convert.ToDouble无法转换为SQL语句,我无法完全弄清楚如何使转换/强制转换工作。

我正在使用Code-first

2 个答案:

答案 0 :(得分:0)

你可以试试这个: IQueryable<Department> query = db.Departments;
query = query.OrderBy(item => SqlFunctions.IsNumeric(item.Code) == 1 ? 0 : 1) .ThenBy(item => SqlFunctions.IsNumeric(item.Code) == 1 ? (double)item.Code : 0); return query.ToList();

答案 1 :(得分:0)

这个怎么样:

int i;
var x = (from d in db.Departments
        select d).ToList()
       .OrderBy(d => int.TryParse(d.Code, out i) ? 0 : 1)
       .ThenBy(d => int.TryParse(d.Code, out i) ? int.Parse(d.Code): 99999999)
       .ThenBy(d => d.Code);
  

编辑SQL Server端

var x= db.Departments
   .OrderBy(d => SqlMethods.Like(d.Code, "%[^0-9]%") ? 0 : 1)
   .ThenBy(m => ("000000000000" + m.Code).Substring(12 + m.Code.Length, 12))

这提供了以下SQL代码:

DECLARE @p0 VarChar(1000) = '%[^0-9]%'
DECLARE @p1 Int = 0
DECLARE @p2 Int = 1
DECLARE @p3 NVarChar(1000) = '000000000000'
DECLARE @p4 Int = 12
DECLARE @p5 Int = 12
SELECT [t0].[Code]
FROM [departments] AS [t0]
ORDER BY 
    (CASE 
        WHEN [t0].[Code] LIKE @p0 THEN @p1
        ELSE @p2
     END), SUBSTRING(@p3 + [t0].[Code], @p4 + LEN([t0].[Code]) + 1, @p5)