2010-05-15 2 views
1

SQL 쿼리를 LINQ로 변환하려고합니다. 어떻게 든 내 count (distinct (x)) 논리가 제대로 작동하지 않는 것 같습니다. 원래 SQL은 매우 효율적입니다 (또는 생각합니다). 그러나 생성 된 SQL은 올바른 결과를 반환하지 않습니다.이 LINQ synatx에서 잘못된 점은 무엇입니까?

원본 SQL이 수행하는 작업을 수행하기 위해이 LINQ를 수정하려고하며 원본 쿼리가 효율적으로 수행하고 있습니다. 여기에 도움이 정말 내가 여기에 붙어로 :(노력하고 있습니다

SQL을 apreciated 난의 비교 LINQ해야 할 것 :

: 나는 대략 다음과 같습니다 만든

SELECT [t1].[PersonID] AS [personid] 
FROM [dbo].[Code] AS [t0] 
INNER JOIN [dbo].[phonenumbers] AS [t1] ON [t1].[PhoneCode] = [t0].[Code] 
INNER JOIN [dbo].[person] ON [t1].[PersonID]= [dbo].[Person].PersonID 
WHERE ([t0].[codetype] = 'phone') AND (
([t0].[CodeDescription] = 'Home') AND ([t1].[PhoneNum] = '111') 
OR 
([t0].[CodeDescription] = 'Work') AND ([t1].[PhoneNum] = '222')) 
GROUP BY [t1].[PersonID] HAVING COUNT(DISTINCT([t1].[PhoneNum]))=2 

LINQ를

var ids = context.Code.Where(predicate); 
      var rs = from r in ids 
        group r by new { r.phonenumbers.person.PersonID} into g 
        let matchcount=g.Select(p => p.phonenumbers.PhoneNum).Distinct().Count() 
        where matchcount ==2 
        select new 
        { 
         personid = g.Key 
        }; 

불행히도 위의 LINQ는 올바른 결과를 생성하지 못하며 실제로 내부적으로 아래 표시된 SQL에 생성됩니다.이 생성 된 쿼리는 약 2 회 정도의 모든 행 (약 19592040)을 읽습니다. 점수에 :(위대한 performan입니다 ce 문제도. 도와주세요/저를 올바른 방향으로 가르쳐주십시오.

Declare @p0 VarChar(10)='phone' 
Declare @p1 VarChar(10)='Home' 
Declare @p2 VarChar(10)='111' 
Declare @p3 VarChar(10)='Work' 
Declare @p4 VarChar(10)='222' 
Declare @p5 VarChar(10)='2' 

SELECT [t9].[PersonID], (
    SELECT COUNT(*) 
    FROM (
     SELECT DISTINCT [t13].[PhoneNum] 
     FROM [dbo].[Code] AS [t10] 
     INNER JOIN [dbo].[phonenumbers] AS [t11] ON [t11].[PhoneType] = [t10].[Code] 
     INNER JOIN [dbo].[Person] AS [t12] ON [t12].[PersonID] = [t11].[PersonID] 
     INNER JOIN [dbo].[phonenumbers] AS [t13] ON [t13].[PhoneType] = [t10].[Code] 
     WHERE ([t9].[PersonID] = [t12].[PersonID]) AND ([t10].[codetype] = @p0) AND ((([t10].[codetype] = @p1) AND ([t11].[PhoneNum] = @p2)) OR (([t10].[codetype] = @p3) AND ([t11].[PhoneNum] = @p4))) 
     ) AS [t14] 
    ) AS [cnt] 
FROM (
    SELECT [t3].[PersonID], (
     SELECT COUNT(*) 
     FROM (
      SELECT DISTINCT [t7].[PhoneNum] 
      FROM [dbo].[Code] AS [t4] 
      INNER JOIN [dbo].[phonenumbers] AS [t5] ON [t5].[PhoneType] = [t4].[Code] 
      INNER JOIN [dbo].[Person] AS [t6] ON [t6].[PersonID] = [t5].[PersonID] 
      INNER JOIN [dbo].[phonenumbers] AS [t7] ON [t7].[PhoneType] = [t4].[Code] 
      WHERE ([t3].[PersonID] = [t6].[PersonID]) AND ([t4].[codetype] = @p0) AND ((([t4].[codetype] = @p1) AND ([t5].[PhoneNum] = @p2)) OR (([t4].[codetype] = @p3) AND ([t5].[PhoneNum] = @p4))) 
      ) AS [t8] 
     ) AS [value] 
    FROM (
     SELECT [t2].[PersonID] 
     FROM [dbo].[Code] AS [t0] 
     INNER JOIN [dbo].[phonenumbers] AS [t1] ON [t1].[PhoneType] = [t0].[Code] 
     INNER JOIN [dbo].[Person] AS [t2] ON [t2].[PersonID] = [t1].[PersonID] 
     WHERE ([t0].[codetype] = @p0) AND ((([t0].[codetype] = @p1) AND ([t1].[PhoneNum] = @p2)) OR (([t0].[codetype] = @p3) AND ([t1].[PhoneNum] = @p4))) 
     GROUP BY [t2].[PersonID] 
     ) AS [t3] 
    ) AS [t9] 
WHERE [t9].[value] = @p5 

고마워요!

+1

답을 모른다. 대신이 설명을 남기고있다. LinqPad를 사용해 보셨습니까? http://www.linqpad.net/ LinqPad는 Joseph Albahari의 무료 도구입니다. http://www.albahari.com/ 그가 관심을 가질만한 몇 가지 기사가 있습니다 (예 : http://www.albahari.com/nutshell/speedinguplinqtosql.aspx). – gerryLowry

+0

네, LINQPad 있습니다. 참으로 유용한 도구입니다. 감사. –

답변

0

Drats! 내 편이 잘못 된 것처럼 보입니다. (GIGO 원리입니다!)

내 ORM에서는 다른 방법 대신 오른쪽에서 왼쪽으로 연관을 만들었습니다. 그게 문제라고 생각합니다.

왼쪽의 문제는 LINQ가 INNER JOIN을 두 번 생성하고있어 최종 결과가 올바르게 검색되도록하는 것입니다. 만약 내가 내가 nthe 생성 된 SQL 주석, 나는 올바른 결과를 얻고있다. 그게 지금 유일한 문제이고, 나는 그것에 대한 새로운 질문을 열어 놓을 것 같아. 시간 내 줘서 고마워!.

0

문제는 new { r.phonenumbers.person.PersonID} 일 수 있다고 생각합니다.

r.phonenumbers.person으로 그룹화하는 것보다 새로운 개체를 새로 만드는 이유가 무엇입니까? new {}는 매번 그룹화되지 않는 다른 객체가 될 것입니다.

사람 단위로 그룹화 한 후 Selectgroup => new {person = group.person, phoneNumbers = group.person.phonenumbers} 전화 번호를 확인한 다음 최종 프로젝션을 확인합니다.

+0

오우는 내가 두 필드로 그룹화하려고했기 때문에 내가 추가 한 오, 왜냐하면 나는 '새로운'것이 필요할 것입니다. 나중에 두 번째 필드를 제거했지만 새 필드를 삭제하는 것을 잊었습니다. 네가하는 말을 해 볼까. –

관련 문제