2017-01-10 5 views
0

이 두 메서드를 하나의 일반화로 병합해야합니다. IQueryable은 IEnumerable을 구현하고, IOrderedQueryable은 IOrderedEnumerable을 구현하며, 첫 번째 메소드는 두 번째가 존재하면 쓸모없는 것처럼 보입니다. 일부 엔티티 프레임 워크는 이유로 그러나 두 번째는 서버 측 쿼리 번역 LINQ (- 투 - SQL)타입을 잃지 않고 일반화

private static IQueryable<T> Pag<T>(IOrderedQueryable<T> data, int totalRows, int reqLength, int pageNum) 
    { 
     if (reqLength == 0) 
      return data; 
     else 
     { 
      int skipRows = reqLength * (pageNum - 1); 
      if (skipRows >= totalRows) 
       skipRows = 0; 
      int diff = totalRows - skipRows; 
      return data.Skip(skipRows).Take(diff > reqLength ? reqLength : diff); 
     } 
    } 

    private static IEnumerable<T> Pag<T>(IOrderedEnumerable<T> data, int totalRows, int reqLength, int pageNum) 
    { 
     if (reqLength == 0) 
      return data; 
     else 
     { 
      int skipRows = reqLength * (pageNum - 1); 
      if (skipRows >= totalRows) 
       skipRows = 0; 
      int diff = totalRows - skipRows; 
      return data.Skip(skipRows).Take(diff > reqLength ? reqLength : diff); 
     } 
    } 

이 방법은 DRY 규칙을 깨고 그것을 몹시 짜증나 나누기.

+1

코드 난독 화가 성공했습니다. 자기 설명 변수 이름을 사용하는 방법을 배웁니다. 즉,이 코드를 어떻게 호출하는지 보여줍니다. – CodeCaster

+0

EF가 Linq에서 SQL로 변환하지 못했음을 보여주기 위해 완벽하고 세밀하고 검증 가능한 예제를 보여줘야합니다. – silentsod

+0

이 코드는 단순히 DB 쿼리의 결과를 페이지 매기기 만합니다. Linq가 IQueryable 컬렉션을 통해 작동하면 linq-to-sql은 DB에서 필요한 행만 검색하는 작업을 수행합니다. IQueryable 메서드에 주석을 추가하는 코드는 어쨌든 IEnumerable 메서드를 사용하여 작동하지만 쿼리는 DB에 작업을 남기지 않고 유해한 성능 효과를내는 대신 DB 처리에서 모든 데이터를 검색합니다. – Max

답변

0

코드가 동일하게 보이더라도 같은 유형에서 작동하지 않으며 제네릭도 사용할 수 없기 때문에 where 절이 여러 개의 지정된 값을 결합 할 수 있습니다.

당신이 할 수있는 것은 모두 계산 논리를 배제하는 것입니다. 그러나 이것이 정말로 더 잘 읽고 유지 보수가 가능하다면 당신의 태도에 달려 있습니다.

private static bool TryCalculateRange(int totalCount, int pageLength, int page, out int skip, out int take) 
{ 
    skip = 0; 
    take = 0; 

    if(pageLength <= 0) 
     return false; 

    skip = pageLength * (page - 1); 

    if(skip >= totalCount) 
     skip = 0; 

    take = totalCount - skip; 

    if(take > pageLength) 
     take = pageLength; 

    return true; 
} 

public static IQueryable<T> Pag<T>(IOrderedQueryable<T> data, int totalRows, int reqLength, int pageNum) 
{ 
    int skip; 
    int take; 

    return TryCalculateRange(totalRows, reqLength, pageNum, out skip, out take)) 
      ? data.Skip(skip).Take(take) 
      : data; 
} 

public static IEnumerable<T> Pag<T>(IOrderedEnumerable<T> data, int totalRows, int reqLength, int pageNum) 
{ 
    int skip; 
    int take; 

    return TryCalculateRange(totalRows, reqLength, pageNum, out skip, out take)) 
      ? data.Skip(skip).Take(take) 
      : data; 
    } 
}