3 回答
TA贡献1868条经验 获得超4个赞
如果您针对 编写 LINQ 查询IQueryable
,会发生什么情况是您在后台调用的方法(例如Select
、Where
等)除了记录您如何调用它们之外没有做任何其他事情,即它们记录谓词表达式并继承一个 LINQ 提供程序。一旦您开始迭代查询,就会要求提供者执行查询模型。所以基本上,提供者使用表达式模型为您提供预期类型的结果。
提供者绝不需要实际编译甚至执行您作为表达式交付的代码(模型)。事实上,LINQ to SQL 或 LINQ to Entities 的全部意义在于提供程序不这样做,而是将代码表达式转换为 SQL。
因此,您的查询实际上被呈现为 SQL 查询,并且该查询的结果被翻译回来。因此,您在查询中看到的变量e
不一定是真正创建的,而只是用于 LINQ 提供程序来编译 SQL 查询。但是,大多数数据库服务器都有空传播。
对 LINQ to Objects 运行相同的查询,您将得到缺少的 NullReferenceException。
TA贡献1848条经验 获得超2个赞
您的更新帮助我了解了您真正关心的问题。关于 LINQ 查询,您需要了解的概念是 LINQ 中的延迟执行。
请通过以下链接了解更多详情:
现在你的情况会怎样?您已将查询存储在location
变量中。该特定步骤只是初始化部分。它并没有真正通过您的 ORM 层对您的数据库执行查询。这就是您可以测试的方式。
location
在使用 LINQ 查询初始化变量的代码行上放置一个断点。当调试器在 Visual Studio 中停止时,请转到 SQL Server Management Studio (SSMS) 并启动 SQL Server Profiler 会话。
现在在 Visual Studio 中按下F10以跳过代码语句。此时,您将在分析器会话中看到绝对没有查询执行,如下所示:
这都是因为 LINQ 查询直到此时才被执行。
现在您可以访问以下代码行:
foreach (var item in location)
{
var p = item.EquipmentClass.EquipmentType.Name;
}
在您进入 foreach 循环的那一刻,LINQ 查询被触发,您将在 SQL Server 探查器中看到相应的登录跟踪会话。因此,除非枚举 LINQ 查询,否则它不会被触发。这称为延迟执行,即运行时延迟执行直到枚举。如果您从未location在代码中枚举变量,那么查询执行将永远不会发生。
因此,要回答您的查询,只有在查询被触发时才会出现异常。不是在那之前!
更新 1:您是说 -我没有得到空引用异常。是的!在您到达缺少相应 RHS 加入记录的记录之前,您不会得到空引用异常。请查看以下代码以更好地理解:
class Program
{
static void Main(string[] args)
{
var mylist1 = new List<MyClass1>();
mylist1.Add(new MyClass1 { id = 1, Name1 = "1" });
mylist1.Add(new MyClass1 { id = 2, Name1 = "2" });
var mylist2 = new List<MyClass2>();
mylist2.Add(new MyClass2 { id = 1, Name2 = "1" });
var location = from l in mylist1
join e in mylist2 on l.id equals e.id into rs1
from e in rs1.DefaultIfEmpty()
//where ids.Contains(l.ID)
select new
{
EquipmentClass = e,
InServiceStatus = e == null ? 1 : e.id,
EquipmentType = e.id
};
foreach (var item in location)
{
}
}
}
class MyClass1
{
public int id { get; set; }
public string Name1 { get; set; }
}
class MyClass2
{
public int id { get; set; }
public string Name2 { get; set; }
}
所以,现在当我开始迭代location变量时,它不会在第一次迭代中中断。它在第二次迭代中中断。当它无法获得与2 中存在的MyClass1对象对应的记录/对象时,它会中断。2没有任何对象。希望这会有所帮助!idmylist1mylist2id
TA贡献1827条经验 获得超8个赞
你的e.EquipmentType.Name
isnull
并且它被分配给它并且分配给一个类型EquipmentType
是非常好的,你正在使用它,如果它不匹配任何条件,它将使用它们的默认值初始化元素,在这种情况下,你被设置为哪个很好我猜。使用它会抛出异常。null
nullable
DefaultIfEmpty()
e.ElementType.Name
null
ToList()
我希望我说得有道理,你们可能已经讨论过这个问题。
- 3 回答
- 0 关注
- 107 浏览
添加回答
举报