2014-09-30 2 views
0

"1", "2", "3", "10"등의 문자열이 있는데 orderby 정렬 목록을 사용하면 "1", "10", "2 ","삼". 1,2,3, ..., 10과 같이 숫자를 정렬하고 싶습니다. 아래 코드를 사용하여 목록을 정렬합니다.엔터티에 linq의 숫자로 정렬 문자열

LINQ to Entities does not recognize the method 'System.Linq.IOrderedQueryable`1[Salary.Classes.ReturnData] OrderBy[ReturnData,String](System.Linq.IQueryable`1[Salary.Classes.ReturnData], System.Linq.Expressions.Expression`1[System.Func`2[Salary.Classes.ReturnData,System.String]], System.Collections.Generic.IComparer`1[System.String])' method, and this method cannot be translated into a store expression. 

그것은 기존 데이터베이스의 다른 응용 프로그램에 오류가 발생 할 수 있기 때문에 내가 어떤 데이터 유형을 변경할 수 없습니다 : 나는이 코드를 실행하면

var model = (from c in General.db.GlbTbComboBases 
      where c.ClassCode.Equals(classCode) 
      select new ReturnData { id = c.BaseCode, name = c.FAName }).OrderBy(c => c.id, 
      new SemiNumericComparer()); 
      if (model.Any()) 
      { 
       CacheManager.cache.GetOrAdd<List<ReturnData>>(key,() => 
       model.ToList<ReturnData>()); 
       return model.ToList<ReturnData>(); 
      } 

public class SemiNumericComparer : IComparer<string> 
     { 
      public int Compare(string s1, string s2) 
      { 
       if (IsNumeric(s1) && IsNumeric(s2)) 
       { 
        if (Convert.ToInt32(s1) > Convert.ToInt32(s2)) return 1; 
        if (Convert.ToInt32(s1) < Convert.ToInt32(s2)) return -1; 
        if (Convert.ToInt32(s1) == Convert.ToInt32(s2)) return 0; 
       } 

       if (IsNumeric(s1) && !IsNumeric(s2)) 
        return -1; 

       if (!IsNumeric(s1) && IsNumeric(s2)) 
        return 1; 

       return string.Compare(s1, s2, true); 
      } 

      public static bool IsNumeric(object value) 
      { 
       try 
       { 
        int i = Convert.ToInt32(value.ToString()); 
        return true; 
       } 
       catch (FormatException) 
       { 
        return false; 
       } 
      } 
     } 

나는이 오류가 발생합니다.

+0

숫자를 문자열 형태로 저장하는 것처럼 보입니다. 필요에 따라 int 또는 decimal로 저장 한 다음 원하는대로 줄 것입니다. –

+1

"자연 정렬 순서"라고합니다. 비교적 쉬운 방법이 있습니다 - [여기 내 대답을보십시오] (http://stackoverflow.com/a/19271974/106159). –

+0

Martin 대단히 감사합니다. –

답변

3

여기서 두 가지 문제가 있습니다

    당신은 당신의 데이터베이스에 문자열로 숫자를 저장하는
  1. 개봉 받고있는 예외는

SQL Server에서 C# 코드를 실행하기 위해 노력을 컴파일러가 SemiNumericComparer 클래스의 비교 로직을 SQL 쿼리로 변환 할 수 없기 때문에. 만약 수 원하는 결과를 달성하기 위해

:

a) 메모리의 모든 데이터를로드하고 이런 그 후 상기 선택된 결과를 반복하고 주문함으로써 메모리 SemiNumericComparer을 사용하여 비교를 수행

var model = (from c in General.db.GlbTbComboBases 
      where c.ClassCode.Equals(classCode) 
      select new ReturnData { id = c.BaseCode, name = c.FAName }) 
      .ToList() // this will load data into memory 
      .OrderBy(c => c.id, new SemiNumericComparer()); 

데이터 집합이 아주 작 으면 많은 쓸모없는 메모리 소비가 추가되고 주어진 시간에 데이터 집합이 사용 가능한 메모리보다 클 경우 응용 프로그램이 중단되므로 좋은 방법은 아닙니다.

B) SqlFunctions 및 SQL Server에서 제공하는 순서를 사용하는 번호와 같은 순서를 사용하여 SQL Server에서 숫자로 문자열을 변환 :

var model = (from c in General.db.GlbTbComboBases 
      where c.ClassCode.Equals(classCode) 
      select new ReturnData { id = c.BaseCode, name = c.FAName }) 
      .OrderBy(c => SqlFunctions.IsNumeric(c.id)); 
0

당신이 numberical 데이터 유형을 정렬 할 수있는 숫자 순서를 원하는 경우 : 이 같은

string[] str = {"1", "10", "2","011"}; 

    List<string> ordered = str.OrderBy(x => int.Parse(x)).ToList(); 
0

시도 뭔가 :

var model = (from c in General.db.GlbTbComboBases 
     where c.ClassCode.Equals(classCode) 
     select new { Id = Convert.ToInt32(c.BaseCode), Name = c.FAName }) 
     .OrderBy(c => c.Id) 
     .Select(x => new ReturnData { id = x.Id, name = x.Name }); 

익명 유형을 정렬에 추가 한 다음 필수 유형으로 변환합니다. 물론 더 많은 메모리가 필요합니다.

관련 문제