2013-07-08 112 views
2

按照entityframework.codeplex.com的建议,我将此问题与标记entity-framework一起发布。LINQ生成不正确的SQL

数据库:在PostgreSQL 9.1 驱动程序:2.0.12 Npgsql的

LINQ查询:

var q1 = customerComplaints 
    .Where(x => x.ParentId == null) 
    .Except(customerComplaints 
       .Where(x => customerComplaints 
           .Any(c => (c.ParentId == x.Id)))); 

var q2 = 
    (from a in customerComplaints 
    join b in 
     (customerComplaints.Where(a => a.ParentId != null) 
          .GroupBy(a => a.ParentId) 
          .Select(b => new { ParentId = b.Key, CreatedDate = b.Max(t => t.CreatedDate) })) 
    on a.ParentId equals b.ParentId 
    where a.CreatedDate == b.CreatedDate 
    select a); 

q1 = q1.Union(q2); 

// Apply Sorting 

if (string.IsNullOrEmpty(sorting) || sorting.Equals("CustomerName ASC")) { 
    q1 = q1.OrderBy(p => p.Customer.Name); 
} else if (sorting.Equals("CustomerName DESC")) { 
    q1 = q1.OrderByDescending(p => p.Customer.Name); 
} else if (sorting.Equals("ManagerName ASC")) { 
    q1 = q1.OrderBy(p => p.Manager.LastName); 
} else if (sorting.Equals("ManagerName DESC")) { 
    q1 = q1.OrderByDescending(p => p.Manager.LastName); 
} else if (sorting.Equals("AssignedName ASC")) { 
    q1 = q1.OrderBy(p => p.Assigned.LastName); 
} else if (sorting.Equals("AssignedName DESC")) { 
    q1 = q1.OrderByDescending(p => p.Assigned.LastName); 
} else if (sorting.Equals("StatusName ASC")) { 
    q1 = q1.OrderBy(p => p.StatusId); 
} else if (sorting.Equals("StatusName DESC")) { 
    q1 = q1.OrderByDescending(p => p.StatusId); 
} else if (sorting.Equals("ComplaintType ASC")) { 
    q1 = q1.OrderBy(p => p.ComplaintTypeId); 
} else if (sorting.Equals("ComplaintType DESC")) { 
    q1 = q1.OrderByDescending(p => p.ComplaintTypeId); 
} else if (sorting.Equals("CreatedDate ASC")) { 
    q1 = q1.OrderBy(p => p.CreatedDate); 
} else if (sorting.Equals("CreatedDate DESC")) { 
    q1 = q1.OrderByDescending(p => p.CreatedDate); 
} 

// Perform paging and execute query 
var result = q1.Skip(startIndex).Take(pageSize).ToList(); 

生成的SQL

SELECT 
"Limit1"."C1" AS "C1" 
"Limit1"."C2" AS "C2"   
"Limit1"."C3" AS "C3" 
"Limit1"."C4" AS "C4"   
"Limit1"."C5" AS "C5"   
"Limit1"."C6" AS "C6"    
"Limit1"."C7" AS "C7"    
"Limit1"."C8" AS "C8"    
"Limit1"."C9" AS "C9"    
"Limit1"."C10" AS "C10"   
"Limit1"."C11" AS "C11"    
"Limit1"."C12" AS "C12"   
"Limit1"."C13" AS "C13"   
"Limit1"."C14" AS "C14"   
"Limit1"."C15" AS "C15"   
"Limit1"."C16" AS "C16"   
"Limit1"."C17" AS "C17"   
"Limit1"."C18" AS "C18"   
"Limit1"."C19" AS "C19"    
"Limit1"."C20" AS "C20"   
"Limit1"."C21" AS "C21"   
"Limit1"."C22" AS "C22" 
FROM 
(SELECT DISTINCT 
    "UnionAll1"."C1" AS "C1"    
    "UnionAll1"."C2" AS "C2" 
    "UnionAll1"."C3" AS "C3"     
    "UnionAll1"."C4" AS "C4"     
    "UnionAll1"."C5" AS "C5"     
    "UnionAll1"."C6" AS "C6"     
    "UnionAll1"."C7" AS "C7"     
    "UnionAll1"."C8" AS "C8"     
    "UnionAll1"."C9" AS "C9"     
    "UnionAll1"."C10" AS "C10"    
    "UnionAll1"."C11" AS "C11"    
    "UnionAll1"."C12" AS "C12"    
    "UnionAll1"."C13" AS "C13"    
    "UnionAll1"."C14" AS "C14"    
    "UnionAll1"."C15" AS "C15"    
    "UnionAll1"."C16" AS "C16"    
    "UnionAll1"."C17" AS "C17"    
    "UnionAll1"."C18" AS "C18"    
    "UnionAll1"."C19" AS "C19"    
    "UnionAll1"."C20" AS "C20"    
    "UnionAll1"."C21" AS "C21"    
    "UnionAll1"."C22" AS "C22" 
FROM 
    (SELECT 
     "Except1"."Id" AS "C1"    
     "Except1"."ManagerId" AS "C2"    
     "Except1"."AssignedId" AS "C3"    
     "Except1"."ComplaintTypeId" AS "C4"    
     "Except1"."RootCauseId" AS "C5"    
     "Except1"."StatusId" AS "C6"     
     "Except1"."ResultingFromId" AS "C7"    
     "Except1"."RespParty" AS "C8"    
     "Except1"."Condition" AS "C9"    
     "Except1"."Containment" AS "C10"     
     "Except1"."CorrectiveAction" AS "C11"    
     "Except1"."ProductRejected" AS "C12"     
     "Except1"."IssueDate" AS "C13"    
     "Except1"."DueDate" AS "C14"     
     "Except1"."Approved" AS "C15"    
     "Except1"."ApprovedById" AS "C16"    
     "Except1"."ApprovedDate" AS "C17"    
     "Except1"."RejectionDetail" AS "C18"     
     "Except1"."Parent" AS "C19"    
     "Except1"."ParentId" AS "C20"    
     "Except1"."CreatedDate" AS "C21"     
     "Except1"."CreatedId" AS "C22" 
    FROM 
     (SELECT 
      "Extent1"."Id" AS "Id", 
      "Extent1"."ManagerId" AS "ManagerId", 
      "Extent1"."AssignedId" AS "AssignedId", 
      "Extent1"."ComplaintTypeId" AS "ComplaintTypeId", 
      "Extent1"."RootCauseId" AS "RootCauseId", 
      "Extent1"."StatusId" AS "StatusId", 
      "Extent1"."ResultingFromId" AS "ResultingFromId", 
      "Extent1"."RespParty" AS "RespParty", 
      "Extent1"."Condition" AS "Condition", 
      "Extent1"."Containment" AS "Containment", 
      "Extent1"."CorrectiveAction" AS "CorrectiveAction", 
      "Extent1"."ProductRejected" AS "ProductRejected", 
      "Extent1"."IssueDate" AS "IssueDate", 
      "Extent1"."DueDate" AS "DueDate", 
      "Extent1"."Approved" AS "Approved", 
      "Extent1"."ApprovedById" AS "ApprovedById", 
      "Extent1"."ApprovedDate" AS "ApprovedDate", 
      "Extent1"."RejectionDetail" AS "RejectionDetail", 
      "Extent1"."Parent" AS "Parent", 
      "Extent1"."ParentId" AS "ParentId", 
      "Extent1"."CreatedDate" AS "CreatedDate", 
      "Extent1"."CreatedId" AS "CreatedId" 
     FROM 
      "dbo"."CorrectiveActionRequest" AS "Extent1" 
     WHERE 
      "Extent1"."ParentId" IS NULL 
     EXCEPT 
      SELECT 
       "Extent2"."Id" AS "Id", 
       "Extent2"."ManagerId" AS "ManagerId", 
       "Extent2"."AssignedId" AS "AssignedId", 
       "Extent2"."ComplaintTypeId" AS "ComplaintTypeId", 
       "Extent2"."RootCauseId" AS "RootCauseId", 
       "Extent2"."StatusId" AS "StatusId", 
       "Extent2"."ResultingFromId" AS "ResultingFromId", 
       "Extent2"."RespParty" AS "RespParty", 
       "Extent2"."Condition" AS "Condition", 
       "Extent2"."Containment" AS "Containment", 
       "Extent2"."CorrectiveAction" AS "CorrectiveAction", 
       "Extent2"."ProductRejected" AS "ProductRejected", 
       "Extent2"."IssueDate" AS "IssueDate", 
       "Extent2"."DueDate" AS "DueDate", 
       "Extent2"."Approved" AS "Approved", 
       "Extent2"."ApprovedById" AS "ApprovedById", 
       "Extent2"."ApprovedDate" AS "ApprovedDate", 
       "Extent2"."RejectionDetail" AS "RejectionDetail", 
       "Extent2"."Parent" AS "Parent", 
       "Extent2"."ParentId" AS "ParentId", 
       "Extent2"."CreatedDate" AS "CreatedDate", 
       "Extent2"."CreatedId" AS "CreatedId" 
      FROM 
       "dbo"."CorrectiveActionRequest" AS "Extent2" 
      WHERE EXISTS 
       (SELECT 
        1 AS "C1" 
       FROM 
        "dbo"."CorrectiveActionRequest" AS "Extent3" 
       WHERE 
        "Extent3"."ParentId"="Extent2"."Id")) AS "Except1" 
       UNION ALL 
        SELECT 
         "Extent4"."Id" AS "Id", 
         "Extent4"."ManagerId" AS "ManagerId", 
         "Extent4"."AssignedId" AS "AssignedId", 
         "Extent4"."ComplaintTypeId" AS "ComplaintTypeId", 
         "Extent4"."RootCauseId" AS "RootCauseId", 
         "Extent4"."StatusId" AS "StatusId", 
         "Extent4"."ResultingFromId" AS "ResultingFromId", 
         "Extent4"."RespParty" AS "RespParty", 
         "Extent4"."Condition" AS "Condition", 
         "Extent4"."Containment" AS "Containment", 
         "Extent4"."CorrectiveAction" AS "CorrectiveAction", 
         "Extent4"."ProductRejected" AS "ProductRejected", 
         "Extent4"."IssueDate" AS "IssueDate", 
         "Extent4"."DueDate" AS "DueDate", 
         "Extent4"."Approved" AS "Approved", 
         "Extent4"."ApprovedById" AS "ApprovedById", 
         "Extent4"."ApprovedDate" AS "ApprovedDate", 
         "Extent4"."RejectionDetail" AS "RejectionDetail", 
         "Extent4"."Parent" AS "Parent", 
         "Extent4"."ParentId" AS "ParentId", 
         "Extent4"."CreatedDate" AS "CreatedDate", 
         "Extent4"."CreatedId" AS "CreatedId" 
        FROM 
         "dbo"."CorrectiveActionRequest" AS "Extent4" 
        INNER JOIN 
         (SELECT 
          "Extent5"."ParentId" AS "K1", 
         CAST 
          (max("Extent5"."CreatedDate") AS timestamp) AS "A1" 
         FROM 
          "dbo"."CorrectiveActionRequest" AS "Extent5" 
         WHERE 
          "Extent5"."ParentId" IS NOT NULL 
         GROUP BY 
          "Extent5"."ParentId") AS "GroupBy1" 
         ON 
          (("Extent4"."ParentId"="GroupBy1"."K1") 
         OR 
          (("Extent4"."ParentId" IS NULL) 
         AND 
          ("GroupBy1"."K1" IS NULL))) 
         AND 
          ("Extent4"."CreatedDate"="GroupBy1"."A1")) AS "UnionAll1") AS "Limit1" 
         ORDER BY "Distinct1"."C7" ASC 
         OFFSET 0 
         LIMIT 10 

罪魁祸首是在最后:

("Extent4"."CreatedDate"="GroupBy1"."A1")) AS "UnionAll1") AS "Limit1" 
         ORDER BY "Distinct1"."C7" ASC 
         OFFSET 0 
         LIMIT 10 

它尝试按Distinct1排序,但在生成的SQL查询中没有其他位置存在此标识符。我一直试图调试这几天,并注意到它依赖于我选择排序。例如,按Customer.Name排序将产生一个工作查询。按照CreatedDate排序不会。

+1

你使用哪个数据库? – Slauma

+1

是的,这是无效的SQL没错,报告一个错误。 –

+0

@Slauma我使用PostreSQL和Npgsql作为驱动程序。 – Alex

回答

3

它可能是指LIMIT1。看起来你正在使用MySQL和MySQL驱动程序有一个错误。我会检查以确保您的驱动程序是最新的,或向他们提交错误。