2016-08-23 38 views
0

我是sql查詢我們產生正確的結果,但是當我在LINQ中做同樣的事情。輸出不正確。請讓我知道我犯了什麼錯誤。LINQ多表左連接,不同的計數沒有給出正確的結果

以下是我創建的linq查詢。

LINQ查詢:

List<UserModel> Model = (from users in db.UserMasters 
        join ct in db.CustTests on users.UserId equals ct.UserID into group1 
        from g1 in group1.DefaultIfEmpty() 
        join ti in db.TestInvitaions on g1.TestId equals ti.TestID into group2 
        from g2 in group2.DefaultIfEmpty() 
        where (users.CustomerId==UserSession.CustomerId) && (users.RoleId == 4) && (users.Status == 1) 
        group new 
        { 
         g2.TestInvitationID, 
         g2.TestID, 
        } 
        by new 
        { 
         users.FirstName, 
         users.CreatedOn, 
         users.Email, 
         users.UserId 
        } into group4 

        select new UserModel 
        { 
         Name = group4.Key.FirstName, 
         CreatedOn = group4.Key.CreatedOn, 
         EmailId = group4.Key.Email, 
         UserId = group4.Key.UserId, 
         NoOfTestTaken = group4.Select(x=>x.TestID).Distinct().Count(), 
         NoOfInvitationsSent = group4.Count(x => x.TestInvitationID != 0) 
        }).ToList(); 

SQL查詢:

SELECT IsNull(COUNT(distinct TS.TestId),0) AS NoOfTests, 
     IsNull(COUNT(TS.TestInvitationID),0) AS NoOfInvitations, 
     UM.Email, 
     UM.UserId, 
     UM.FirstName, 
     UM.CreatedOn 
FROM UserMaster as UM 
left JOIN CustTest AS CT 
ON UM.UserId=CT.UserId 
left JOIN TestInvitaions AS TS 
ON TS.TestId = CT.TestId 

WHERE UM.CustomerId=41 
AND UM.RoleId=4 
and UM.[Status]=1 

GROUP BY UM.UserId, UM.Email, UM.FirstName, UM.CreatedOn 

表:

  • 「UserMaster」 - 列:用戶ID,電子郵件,名字,CreatedOn
  • 「CustTest 「 - 列:TestId,UserId,
  • 「TestInvitaions」 - 列:TestInvitationId,TestId
+0

是sql查詢洙給出正確的結果......根據該參考PLZ回答 – Gaurry

+0

請解釋一下你得到什麼你並沒有期待。一些示例數據和預期的輸出也會有幫助 –

+0

我的sql查詢是正確的soo plz使它成爲LINQ – Gaurry

回答

2

SQL COUNT(expr)之間的區別和LINQ Count是前者不包括NULL值,在左外部連接的右側使用而沒有匹配的記錄時會產生差異(SQL將生成0而LINQ 1)。最接近的LINQ等價物是Count(expr != null)

那麼您的SQL查詢的直接翻譯會是這樣(請注意,生成的SQL查詢可以和最有可能會有所不同):

(旁註:當SQL查詢轉換爲LINQ,它是好使用相同的別名,使其更容易看到的映射)

var query = 
    from um in db.UserMasters 
    join ct in db.CustTests on um.UserId equals ct.UserID 
    into ctGroup from ct in ctGroup.DefaultIfEmpty() // left outer join 
    join ts in db.TestInvitaions on ct.TestId equals ts.TestID 
    into tsGroup from ts in tsGroup.DefaultIfEmpty() // left outer join 
    where um.CustomerId == UserSession.CustomerId 
     && um.RoleId == 4 
     && um.Status == 1 
    group ts by new { um.UserId, um.Email, um.FirstName, um.CreatedOn } into g 
    select new UserModel 
    { 
     Name = g.Key.FirstName, 
     CreatedOn = g.Key.CreatedOn, 
     EmailId = g.Key.Email, 
     UserId = g.Key.UserId, 
     NoOfTestTaken = g.Where(ts => ts != null).Select(ts => ts.TestID).Distinct().Count(), 
     NoOfInvitationsSent = g.Count(ts => ts != null) 
    }; 

var result = query.ToList(); 
+1

噢,不錯,忘記了與計數在左空加入:)好一個 –

+0

感謝你........其給予正確的結果 – Gaurry

+1

感謝lvan Stoev&Gilad Green – Gaurry

0

我懷疑是以下行是問題,因爲不像在SQL一樣:

  • 的Linq:

    NoOfInvitationsSent = group4.Count(x => x.TestInvitationID != 0) 
    
  • SQL:

    IsNull(COUNT(TS.TestInvitationID),0) AS NoOfInvitations 
    
  • 由於從左至右的項目加入LINQ的應該是代替:

    NoOfInvitationsSent = group4.Where(i => i != null).Count() 
    

爲了把它放在一起,用好一點的格式:

var model = (from users in db.UserMasters 
      join ct in db.CustTests on users.UserId equals ct.UserID into group1 
      from ct in group1.DefaultIfEmpty() 
      join ti in db.TestInvitaions on ct.TestId equals ti.TestID into group2 
      from ct in group2.DefaultIfEmpty() 

      where users.CustomerId == UserSession.CustomerId && 
        users.RoleId == 4 && 
        users.Status == 1 

      group new { ct.TestInvitationID, ct.TestID } 
      by new 
      { 
       users.FirstName, 
       users.CreatedOn, 
       users.Email, 
       users.UserId 
      } into grouping 

      select new UserModel 
      { 
       Name = grouping.Key.FirstName, 
       CreatedOn = grouping.Key.CreatedOn, 
       EmailId = grouping.Key.Email, 
       UserId = grouping.Key.UserId, 
       NoOfTestTaken = grouping.Where(i => i != null).Select(x => x.TestID).Distinct().Count(), 
       NoOfInvitationsSent = grouping.Where(i => i != null).Count() 
      }).ToList(); 
+0

我已經嘗試過以上解決方案但尚未開始工作 – Gaurry

+0

@Gaurry - 然後請再次根據上面的要求解釋您的數據是什麼,您獲得的是什麼,正在期待。當你說「不工作」,你必須解釋這意味着什麼...... –