2010-03-18 5 views
7

DAL로 LINQ-SQL을 사용하고 BLL 역할을하는 DB 프로젝트가 있습니다. 다양한 응용 프로그램은 BLL에 액세스하여 SQL 데이터베이스에서 데이터를 읽고 씁니다. 모든 꽤 똑바로 앞으로 내가 생각이러한 LINQ 쿼리의 차이점은 무엇입니까?

public IEnumerable<SystemSalesTaxList> Get_SystemSalesTaxList() 
{ 
     return from s in db.SystemSalesTaxLists 
       select s; 
} 

public SystemSalesTaxList Get_SystemSalesTaxList(string strSalesTaxID) 
{ 
    return Get_SystemSalesTaxList().Where(s => s.SalesTaxID == strSalesTaxID).FirstOrDefault(); 
} 

public SystemSalesTaxList Get_SystemSalesTaxListByZipCode(string strZipCode) 
{ 
    return Get_SystemSalesTaxList().Where(s => s.ZipCode == strZipCode).FirstOrDefault(); 
} 

:

나는 하나 개의 특정 테이블에 대한 내 BLL에서 이러한 방법이있다.

Get_SystemSalesTaxListByZipCode은 해당 테이블에 우편 번호가있는 경우에도 항상 null 값을 반환합니다.

public SystemSalesTaxList Get_SystemSalesTaxListByZipCode(string strZipCode) 
{ 
    var salesTax = from s in db.SystemSalesTaxLists 
        where s.ZipCode == strZipCode 
        select s; 

    return salesTax.FirstOrDefault(); 
} 

왜 다른 방법은 쿼리로 동일해야 같은 반환하지 않습니다 :이 같은 방법을 작성하는 경우

, 내가 원하는 행을 반환?

오버플로 된 Get_SystemSalesTaxList(string strSalesTaxID)은 유효한 SalesTaxID을 제공 할 때 레코드를 정상적으로 반환합니다.

"헬퍼"유형 클래스를 작성하는보다 효율적인 방법이 있습니까?

감사합니다.

+0

바보 질문 - ZipCode를'Get_SystemSalesTaxListByZipCode'에 전달하고 있습니까? – Oded

+1

문제는 "IEnumerable "입니다.하지만 "아마도 그것은 헝가리 표기법에 대해 불평할만한 방법 일 것입니다"라고 울부 짖는 중입니다 .-p –

답변

7

이것은 LINQ가 IEnumerable<T>IQueryable<T>을 처리하는 여러 가지 방법에 기인합니다.

Get_SystemSalesTaxListIEnumerable<SystemSalesTaxList>으로 반환한다고 선언했습니다. 즉, 첫 번째 코드 샘플에서 Where 연산자를 Get_SystemSalesTaxList의 결과에 적용하면 Enumerable.Where 확장 메서드로 해석됩니다. (. 어떤 중요한 것은 IQueryable<SystemSalesTaxList>을 반환 런타임 Get_SystemSalesTaxList에서, 예를 선언 유형 있습니다,하지만 선언 타입 - 컴파일러는보고 무슨 일이 - IEnumerable<SystemSalesTaxList>입니다.) Enumerable.Where 대상을 통해 지정된 .NET 술어를 실행 순서. 이 경우 Get_SystemSalesTaxList에 의해 반환 된 모든 SystemSalesTaxList 개체를 반복하여 ZipCode 속성이 지정된 Zip 코드 문자열과 같아집니다 (.NET 문자열 == 연산자 사용).

마지막 코드 샘플에서는 IQueryable<SystemSalesTaxList> 인 것으로 선언 된 db.SystemSalesTaxList에 Where 연산자를 적용합니다. 따라서 해당 샘플의 Where 연산자는 지정된 술어 표현식을 SQL로 변환하고 데이터베이스에서 실행하는 Queryable.Where으로 해석됩니다.

우편 번호 방법의 차이점은 첫 번째 테스트에서는 .NET에서 C# s.ZipCode == strZipCode 테스트를 실행하고 두 번째 쿼리는 SQL 쿼리 WHERE ZipCode = 'CA 12345' (실제로는 매개 변수가 있지만 아이디어는 얻을 수 있음)로 변환한다는 것입니다. 왜 다른 결과를 내는가? 확실치 않지만 C# == 조건자는 대/소문자를 구분하며 데이터 정렬 설정에 따라 SQL에서 대/소문자를 구분할 수도 있고 대소 문자를 구분하지 않을 수도 있습니다. 따라서 내 의심으로 strZipCode은 데이터베이스 우편 번호와 일치하지 않지만 두 번째 버전에서는 SQL Server 데이터 정렬이 문제를 해결합니다.

가장 좋은 해결책은 아마도 Get_SystemSalesTaxList 선언을 변경하여 IQueryable<SystemSalesTaxList>을 반환하는 것입니다. 이것의 주요 장점은 Get_SystemSalesTaxList에 빌드 된 쿼리가 데이터베이스 측에서 실행된다는 것을 의미합니다.현재 귀하의 방법은 EVERYTHING을 데이터베이스 테이블에서 철회하고 클라이언트 쪽을 필터링합니다. 선언을 변경하면 쿼리가 SQL로 변환되어 더 효율적으로 실행되며 우편 번호 문제를 협상으로 해결할 수 있습니다.

+0

나에게 의미가 있으며 정확하게 대답 나는 질문을 게시 할 때 찾고 있었어! 고맙습니다. – SnAzBaZ

1

실제 문제는 IEnumerable<T>의 사용으로 쿼리의 "구성"을 손상시킵니다. 이 두 가지 효과가 있습니다

  • 당신이 하나의 행
  • 실행중인 요청 한 경우에도 모든 (또는 적어도, 당신이 필요로하는 것보다 더 많은) 테이블의 때마다 읽는을 LINQ - 투 - 객체 규칙, 그래서 대소 문자 구분이 대신

적용, 당신은 필요에 따라 추가 Where, OrderBy, Skip, Take 등 여러 쿼리를 결합 할 수 있도록 데이터 층 내부 IQueryable<T>를 사용하고 싶은가를 구축해야 TSQL 일치하도록 (그리고 DB의 대/소문자 구분 규칙을 사용하십시오).

이러한 "도우미"유형 클래스를 작성하는 효율적인 방법이 있습니까? 보다 효율적인 들어

(디버그에 적은 코드는 FirstOrDefault 등)을 통해 전체 표, 단락 추가 조회로 신원 맵 (보다 효율적으로 사용하는 스트리밍되지 않음) :

public IEnumerable<SystemSalesTaxList> Get_SystemSalesTaxList() 
{ 
    return db.SystemSalesTaxLists; 
} 

public SystemSalesTaxList Get_SystemSalesTaxList(string salesTaxID) 
{ 
    return db.SystemSalesTaxLists.FirstOrDefault(s => s.SalesTaxID==salesTaxID); 
} 

public SystemSalesTaxList Get_SystemSalesTaxListByZipCode(string zipCode) 
{ 
    return db.SystemSalesTaxLists.FirstOrDefault(s => s.ZipCode == zipCode); 
} 
+0

내 메모를 참조하십시오 (http://stackoverflow.com/questions/2469816/what-is-the-best-way-to-determine-if-table-already-has-record-with-specific-id/). 2469836 # 2469836) .NET 3.5/3.5SP1/4.0 사이의'Where (predicate) .FirstOrDefault()'와'FirstOrDefault (predicate)'의 차이점에 대해서 –

+0

고맙습니다. – SnAzBaZ

관련 문제