这真让我疯狂,我无法弄清楚为什么希望有人能给我一点暗示为什么它会如此表现。我有4张桌子
这两个表中的第一组,能够给我一个干净漂亮的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; }
}
使用Above表格,我使用它 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
问题
答案 0 :(得分:1)
C1列似乎与查询无关 - 它可能是自动发生的优化或保护,因此LINQ无法意外地创建无效的内容 - 或者可能是第一行不能无意中具有NULL值。
生成C2列作为对空值的保护,因为该值被归为主键(这意味着它不能为空)。由于您正在进行LEFT OUTER JOIN,因此左侧的值可能没有连接记录 - 但仍必须显示LEFT信息的有效行。
查询看起来更复杂,因为它在选择结果之前在临时表中构造此额外信息。这可能是以这种方式解决问题,因为这是它知道如何通过代码生成它的唯一方式 - 或者它可能足够聪明,知道这个查询对于查询来说稍微更优化引擎(我可能不会赌它)。
答案 1 :(得分:1)
在第一种情况下,您正在为简单导航属性执行Include (因此可以使用简单的左外连接完成,响应中的每一行将在结果中实现为实体), 在第二种情况下包含集合,因此结果中的几行应合并为单个实体及其集合属性。因此,SQL查询必须以下列方式编写: 1.将在单个实体中合并的所有行将按顺序获取 2.促进检测群体界限的过程 3.减少数据重复 在这种简单的情况下,可以消除生成的SQL的某些部分,但是当e.t.c中包含多个集合属性时,它们将用于更复杂的查询。