2014-06-30 38 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的某些部分可以是在这个简单的例子中被淘汰,但是当包含几个集合属性时,它们被用在更复杂的查询中

相关问题