2011-09-17 2 views
0

내 INT 년대에 신비 "1"을 추가 .... 내가 LINQ 아래의 SQL 방법에있다 ->LINQ 난, 난 그냥 난처한 상황에 빠진를 예정하고 인정해야 생성 된 SQL

public static int GetLastInvoiceNumber(int empNumber) 
    { 
     using (var context = CmoDataContext.Create()) 
     { 
      context.Log = Console.Out; 

      IQueryable<tblGreenSheet> tGreenSheet = context.GetTable<tblGreenSheet>(); 
      return (tGreenSheet 
          .Where(gs => gs.InvoiceNumber.Substring(3, 4) == empNumber.ToString()) 
          .Max(gs => Convert.ToInt32(gs.InvoiceNumber.Substring(7, gs.InvoiceNumber.Length))) 
          ); 
     } 
    } 

를이했다 거의 같은 일 을 달성하기 위해 동료에 의해 작성된 SQL 쿼리에서 기반으로 만든 ->

- 그러나>

SELECT DISTINCT 
SUBSTRING([InvoiceNumber], 1, 6) AS EmpNumber, 
MAX(CAST(SUBSTRING([InvoiceNumber], 7, LEN([InvoiceNumber])) AS INT)) AS MaxInc 
FROM [CMO].[dbo].[tblGreenSheet] 
WHERE SUBSTRING([InvoiceNumber], 3, 4) = '1119' --EmployeeNumber 
GROUP BY SUBSTRING([InvoiceNumber], 1, 6) 

, 생성되고있는 SQL, 내가 context.Log = Console.Out를 통해 확인이입니다

SELECT MAX([t1].[value]) AS [value] 
FROM (
    SELECT CONVERT(Int,SUBSTRING([t0].[InvoiceNumber], @p0 + 1, LEN([t0].[InvoiceNumber]))) AS [value], [t0].[InvoiceNumber] 
    FROM [dbo].[tblGreenSheet] AS [t0] 
    ) AS [t1] 
WHERE SUBSTRING([t1].[InvoiceNumber], @p1 + 1, @p2) = @p3 
-- @p0: Input Int (Size = 0; Prec = 0; Scale = 0) [7] 
-- @p1: Input Int (Size = 0; Prec = 0; Scale = 0) [3] 
-- @p2: Input Int (Size = 0; Prec = 0; Scale = 0) [4] 
-- @p3: Input VarChar (Size = 4; Prec = 0; Scale = 0) [1119] 

실제로는 글래리을 제외하고는 꽤 가까운 것을 볼 수 있습니다. 일부는 +1의 것을 추가했습니다 !!!

WTH?!?

심지어 생성 된 SQL에서 +1을 제거하고 원본 SQL과 동일한 결과를 생성하여 실행하는 것으로 올바른지 확인했습니다.

그래서 무엇이 잘못되었거나 잘못 되었습니까? 이게 잘 알습니까 LOL의 LINQ는 덜 재능있는 프로그래머와 함께 할 수 있습니까?

답변

5

SQL Server의 SUBSTRING은 1부터 시작하는 인덱싱을 사용하는 반면 string.Substring에서는 0부터 시작하는 인덱싱을 사용합니다. + 1은 C# 의미를 보존하기 위해 기본 사이를 매핑합니다.

정확하게 작동하게하려면 + 1을 제거해야하는 이유는 내게 신비입니다. @MarceloCantos 대답

+0

나는 볼 수 있지만 LINQ 버전은 전혀 작동하지 않습니다. 일치하는 것이 없으므로 NULL을 반환합니다. 하지만 SQL 버전이 작동하고 LINQ/SQL 덤프가 + 1의 –

+0

BTW없이 작동한다는 것을 알고 있습니다. 설명해 주셔서 감사합니다. 왜 작동하지 않는지 알고 싶습니다. –

2

는 정확하지만 여기와 같이 제거 할 때 작동하는 이유에 대한 설명입니다 + 1 : 당신은 gs.InvoiceNumber.Substring(3, 4)에 있지만 C 번호는 제로로부터 시작되는 인덱스를 사용하기 때문에 실제로 gs.InvoiceNumber.Substring(2, 4)를 사용해야합니다 SUBSTRING([InvoiceNumber], 3, 4)를 변환 한

세 번째 문자에서 시작합니다.

마찬가지로 SUBSTRING([InvoiceNumber], 7, LEN([InvoiceNumber])) 대신 gs.InvoiceNumber.Substring(6)을 사용해야합니다. 인덱스 뒤에있는 모든 것을 원한다면 C#에서 부분 문자열의 길이를 지정할 필요가 없습니다. 실제로 gs.InvoiceNumber.Substring(7, gs.InvoiceNumber.Length)ArgumentOutOfRangeException을 별도로 사용하려고 시도하지만 실제로는 T-SQL로 변환되어 실제로 작동합니다.

참고로 SUBSTRING([InvoiceNumber], 1, 6) AS EmpNumber은 처음 6자를 나타내는 것으로 보입니다.이 숫자는 EmployeeNumber이지만 마지막 네 개만 보았습니다. 아마 < 10000 명의 직원 만 있기 때문에 나중에 물어볼 수도 있습니다.

가독성을 높이기 위해 위의 메서드를 분해하고 적절한 이름을 지정하는 것이 좋습니다. 예 : getEmployeeNumber(string invoiceNumber)

관련 문제