2014-06-30 39 views
0

這真的讓我發瘋,我無法弄清楚爲什麼希望有人可以給我一點暗示爲什麼它的行爲如此。我有4個表爲什麼不同的T-SQL產生幾乎相同的表結構

第一組這兩個表的,並能夠給我一個乾淨,漂亮的T-SQL(從this link樣品)

public class Standard 
{ 
    public Standard() 
    { 
     Students = new List<Student>(); 
    } 
    public int StandardId { get; set; } 
    public string StandardName { get; set; } 
    public string Description { get; set; } 

    public virtual ICollection<Student> Students { get; set; } 
} 

public class Student 
{ 
    public Student() { } 

    public int StudentId { get; set; } 
    public string StudentName { get; set; } 

    public virtual Standard Standard { get; set; } 

} 

上面的表,我用這個 LINQ

List<Student> student = context.student.ToList(); 


var r = from ord in context.student.Include("standard") 
     select ord; 

輸出繼電器

SELECT 
[Extent1].[StudentId] AS [StudentId], 
[Extent1].[StudentName] AS [StudentName], 
[Extent2].[StandardId] AS [StandardId], 
[Extent2].[StandardName] AS [StandardName], 
[Extent2].[Description] AS [Description] 
FROM [dbo].[Students] AS [Extent1] 
LEFT OUTER JOIN [dbo].[Standards] AS [Extent2] ON [Extent1].[Standard_StandardId] = [Extent2].[StandardId] 

但隨着第二組

public partial class Cust_ProfileTbl 
{ 
    public Cust_ProfileTbl() 
    { 
     balance = new List<BP_BalanceTbl>(); 
    } 
    [Key] 
    public virtual long bintAccountNo { get; set; } 
    public string varCardNo { get; set; } 


    public virtual ICollection<BP_BalanceTbl> balance { get; set; } 


} 


public class BP_BalanceTbl 
{ 
    public BP_BalanceTbl() { } 
    public virtual long bintAccountNo { get; set; } 
    [Key] 
    public int intid { get; set; } 
    public virtual Cust_ProfileTbl profile { get; set; } 

} 

與此LINQ

List<Cust_ProfileTbl> profile = context.profile.ToList(); 

var rs = from ord in context.profile.Include("balance") 
     select ord; 

輸出

SELECT 
[Project1].[C1] AS [C1], 
[Project1].[bintAccountNo] AS [bintAccountNo], 
[Project1].[varCardNo] AS [varCardNo], 
[Project1].[C2] AS [C2], 
[Project1].[intid] AS [intid], 
[Project1].[bintAccountNo1] AS [bintAccountNo1] 
FROM (SELECT 
    [Extent1].[bintAccountNo] AS [bintAccountNo], 
    [Extent1].[varCardNo] AS [varCardNo], 
    1 AS [C1],  --Why it generate this>? 
    [Extent2].[intid] AS [intid], 
    [Extent2].[bintAccountNo] AS [bintAccountNo1], 
    CASE WHEN ([Extent2].[intid] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C2] --Why it generate this>? 
    FROM [dbo].[Cust_ProfileTbl] AS [Extent1] 
    LEFT OUTER JOIN [dbo].[BP_BalanceTbl] AS [Extent2] ON [Extent1].[bintAccountNo] = [Extent2].[bintAccountNo] 
) AS [Project1] 
ORDER BY [Project1].[bintAccountNo] ASC, [Project1].[C2] ASC 

問題

  1. 爲什麼在第二LINQ它的產生C1?
  2. 爲什麼在第二LINQ有這樣的線CASE WHEN([Extent2]。[intid] IS NULL)THEN CAST(NULL as int)ELSE 1 END AS [C2] - 爲什麼它產生這個?
  3. 爲什麼第二個輸出是如此複雜?

回答

1
  1. 的C1列似乎並不相關的查詢 - 這可能是使LINQ不會意外地創造一些無效時自動發生的優化和保護 - 或許,使得第一行不能無意中有NULL值。

  2. 由於該值被歸爲主鍵(這意味着它不能爲空),所以生成C2列作爲針對空值的保護。由於您正在執行LEFT OUTER JOIN,因此左側的值可能沒有連接記錄 - 但仍必須顯示有效的LEFT信息行。

  3. 查詢只看起來更復雜,因爲它在選擇結果之前在臨時表中構造這些額外的信息。它可能是以這種方式放置查詢,因爲這是它知道如何通過代碼生成它的唯一方式 - 或者它可以足夠聰明地知道這個查詢對於查詢引擎來說稍微更優化(我可能不會下注在那)。

1

在你正在做包括簡單的導航屬性 第一種情況下(因此它可以用簡單的左外連接,並響應各行完成將物化爲結果的實體),在第二種情況下收集, 是因此從結果中包含幾行應合併成單個實體及其集合屬性。因此,SQL查詢必須按以下方式編寫: 1.將按順序提取要在單個實體中合併的所有行 2.便於檢測組邊界的過程 3.減少數據重複 生成的SQL的某些部分可以是在這個簡單的例子中被淘汰,但是當包含幾個集合屬性時,它們被用在更復雜的查詢中

相關問題