2010-05-15 72 views
1

我想將一個SQL查詢轉換爲LINQ。不知何故,我的計數(distinct(x))邏輯似乎沒有正常工作。原始的SQL非常有效(或者我認爲),但生成的SQL甚至不會返回正確的結果。這個LINQ synatx怎麼了?

我想解決這個LINQ做什麼原始SQL正在做,並在原有查詢正在做一個有效的方式。在這裏幫助將是非常apreciated因爲我在這裏停留:(

SQL這是工作,我需要做的相當的LINQ:

​​

的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。順便說一句,這個生成的查詢也讀取所有行(約19592040)到COUNTS :(這是一個很大的表演也是問題。請幫助/指向正確的方向。

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 g。 – gerryLowry 2010-05-15 06:56:47

+0

是的,我有LINQPad。它確實是一個方便的工具。謝謝。 – 2010-05-15 07:29:54

回答

0

Drats!它看起來像故障是在我身邊(GIGO原則!)

在我的ORM,我創造了從右到左的關聯,而不是反過來。我認爲這是問題。

唯一的問題現在剩下的現象的原因是LINQ是生成一個INNER JOIN兩次,那就是保持最後的結果要正確檢索。如果我註釋它在生成的SQL,我得到正確的結果。這是現在唯一的問題,我想我會爲此提出一個新問題。謝謝你的時間!。

0

我認爲問題可能是new { r.phonenumbers.person.PersonID}

爲什麼在這裏新建一個新對象,而不是直接按r.phonenumbers.person進行分組?新{}將成爲不同的對象,每次永遠不會分組。

經過人員分組後,我會Select a group => new {person = group.person, phoneNumbers = group.person.phonenumbers}然後檢查他們有多少電話號碼,然後進行最終投影。

+0

哦,我已經添加了,因爲我自己試圖分成兩個領域,爲此我想我需要'新'。後來我刪除了第二個字段,但忘記刪除新的字段。讓我試試你在說什麼。 – 2010-05-15 06:59:29