下面的查询包含多个INNER JOIN
子句。
Student
表有很多外键,它们被查询中的名称替换。我在下面使用LEFT OUTER JOIN
查询。请注意MarkID
中的Students
可以是null
。这意味着marksGroup.DefaultifEmpty()
也可能会返回null
。因此,如果我在最后一行只放置m
而不是m != null ? m.MarkName : "-- Not marked --"
,则代码IMO应该在m
为空时抛出异常,因为我指的是这个变量,但它没有。在我构建此查询的示例中,编译器抛出异常。请参阅代码:
var result = from st in dbContext.Students where st.DepartmentID == 17
join d in dbContext.Departments on st.DepartmentID equals d.DepartmentID
join sv in dbContext.SoftwareVersions on st.SoftwareVersionID equals sv.SoftwareVersionID
join stat in dbContext.Statuses on st.StatusID equals stat.StatusID
join m in dbContext.Marks on st.MarkID equals m.MarkID into marksGroup
from m in marksGroup.DefaultIfEmpty()
select new
{
student = st.StudentName,
department = p.DepartmentName,
software = sv.SoftwareVersionName,
status = st.StatusName,
marked = m != null ? m.MarkName : "-- Not marked --"
};
我错过了什么。我仍然是 C#和 LINQ 的初学者。
答案 0 :(得分:1)
当你针对SQL后端执行LINQ语句时(我假设你在这里有Entity Framework),整个语句被转换为SQL并由数据库引擎执行。
这就是.Net运行时的作用:
Expression
)翻译成SQL 在您的情况下,部件
可以安全地定义要创建的对象select new
{
student = st.StudentName,
department = p.DepartmentName,
software = sv.SoftwareVersionName,
status = st.StatusName,
marked = m.MarkName
}
.Net运行时唯一关注的是创建匿名类型的实例,并从结果集中的一行设置其属性。在某些行中,marked
的值可能为null
,因此marked
将在该特定对象中设置为null
。 .Net运行时不处理那里的MarksGroup
对象。
当然在LINQ对象中,这将完全不同。那里必须进行空检查以防止空对象引用。