Sud*_*002 3 c# linq linq-to-entities
我正在使用LINQ to Entities从数据库中获取一些数据。以下是我的查询。
var location = from l in dbContext.Locations
join e in dbContext.Equipment on l.ID equals e.LocationID into rs1
from e in rs1.DefaultIfEmpty()
where ids.Contains(l.ID)
select new
{
EquipmentClass = e,
LocationID = l.ID,
LocationName = l.Name,
EquipmentName = e == null ? null : e.Name,
Description = e == null ? null : e.Description,
InServiceStatus = e == null ? false : e.InServiceStatus,
EquipmentType = e.EquipmentType.Name
};
foreach (var item in location)
{
// some logic
}
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,ids是我传递以过滤结果的int列表。当得到结果时,我看到返回记录之一为null EquipmentClass。我执行了一些空检查,但意识到我忘记对其中一个属性进行空检查。现在,我希望得到一个空引用异常,EquipmentType = e.EquipmentType.Name但我没有。令我惊讶的是,它工作得很好,并且设置为null。My EquipmentClass的属性类型为EquipmentType,是另一类。EquipmentType具有Name一个字符串属性。
就像一个测试一样,我从中删除了空检查,InServiceStatus = e == null ? false : e.InServiceStatus并且在使用查询运行foreach循环时,它以无效的操作异常失败。
更新:
foreach (var item in location)
{
var p = item.EquipmentClass.EquipmentType.Name;
}
Run Code Online (Sandbox Code Playgroud)
在查询后立即添加此内容。关于p的赋值,我得到一个空引用异常。我不确定它到底能走多远,因为它应该在foreach循环的第一行失败。没有声明变量p的行,我不会得到null引用异常。如果有人能解释发生了什么,我将不胜感激。仅供参考,在foreach循环开始时,item.EquipmentClass和的值item.EquipmentType都为空。
Update2: 我发现此链接在哪里似乎有人使用LINQ to SQL几乎存在相同的问题。我得到了答案的要点,但并不完全理解它对上面两个问题的潜在影响。
如果你写对LINQ查询IQueryable,什么情况是,这些方法,你是在幕后调用(如Select,Where等)没有做任何事情不仅仅是记录你怎么称呼他们,也就是说,它们记录了谓词表达式并继承LINQ提供程序。一旦开始迭代查询,就会要求提供程序执行查询模型。因此,基本上,提供程序使用表达式模型为您提供预期类型的结果。
完全不需要编译器实际编译甚至执行您作为表达式提供的代码(模型)。实际上,LINQ to SQL或LINQ to Entities的全部要点是提供程序不执行此操作,而是将代码表达式转换为SQL。
因此,您的查询实际上呈现为SQL查询,并且该查询的结果被转换回。因此,e您在查询中看到的变量不一定是真正创建的,而是仅用于LINQ提供程序来编译SQL查询。但是,大多数数据库服务器的传播为空。
针对LINQ to Objects运行相同的查询,您将得到缺少的NullReferenceException。