C# 实体框架-在空对象上强制转换属性不';你不会抛出异常吗?
我正在查看一些遗留代码,发现了一个代码片段,它似乎会抛出不需要的异常。本质上,代码(EntityFramework查询)如下所示:C# 实体框架-在空对象上强制转换属性不';你不会抛出异常吗?,c#,linq,entity-framework,C#,Linq,Entity Framework,我正在查看一些遗留代码,发现了一个代码片段,它似乎会抛出不需要的异常。本质上,代码(EntityFramework查询)如下所示: var serviceId = (Guid?) person.Services.FirstOrDefault(s => s.Name == "foo").Id; bool inService = serviceId.HasValue; (T?) entity.<non-existent entity>.SomeProperty 也就是说,一个人
var serviceId = (Guid?) person.Services.FirstOrDefault(s => s.Name == "foo").Id;
bool inService = serviceId.HasValue;
(T?) entity.<non-existent entity>.SomeProperty
也就是说,一个人
分配了多个服务,我们将返回其名称
为foo
的第一个服务。然后,我们获取该服务
实例的Id属性(Guid),并将其转换为可为空的Guid。最后,如果该可为空的Guid有一个值,则该人员必须在该服务中
(注意:我不会选择这样写上面的内容,这只是我正在处理的问题)
我有一种感觉,当这个人不属于名为“foo”的服务(或者实际上是任何服务)时,这个代码只会抛出异常,因为FirstOrDefault
调用将返回一个null
service
实例,访问Id
属性只会抛出一个NPE
我向最初的开发人员询问了这段代码,他们告诉我要执行以下操作:
var serviceId = (Guid?) person.Services.FirstOrDefault(s => s.Name == "foo").Id;
bool inService = serviceId.HasValue;
(T?) entity.<non-existent entity>.SomeProperty
(T?)实体..SomeProperty
将只返回一个空对象,而不是抛出一个NPE。此外,这种类型的“安全空处理”也发生在实体框架查询中
这似乎难以置信地违反直觉,甚至感觉不可能。我试着研究这个,但我没有发现任何类似的东西。有没有人有这方面的经验?我百分之百地高兴地发现我错了,并且学到了一些新的东西,但我觉得这并不正确
作为补充,我确实尝试过使用EntityFramework连接在Linqpad中运行上面的查询,并且在尝试访问null objects属性时确实生成了一个NPE。EntityFramework将确保实体上所有复杂类型的属性都不是
null
,但它将为该查询返回null
结果。FirstOrDefault
将为对象返回null
。EntityFramework将确保实体上所有复杂类型的属性都不是null
,但它将为该查询返回null
结果。当您说“但它将为该查询返回null结果”时,您的意思是这将返回null:person.Services.FirstOrDefault(s=>s.Name==“foo”
?或者这样:(Guid?)person.Services.FirstOrDefault(s=>s.Name==“foo”).Id
(包括.Id属性访问器和cast)?FirstOrDefault
将为服务实体返回null,因此您调用的等价项是返回(null).Id
FirstOrDefault
默认值(T)
如果序列为空,对于类默认值(T)
为空。谢谢-这正是我所期望的:)当你说“但它将为该查询返回空结果”时,你的意思是这将返回空值:person.Services.FirstOrDefault(s=>s.Name==“foo”
?还是这:(Guid?)person.Services.FirstOrDefault(s=>s.Name==“foo”).Id
(包括.Id属性访问器和强制转换)FirstOrDefault
将为服务实体返回null,因此您调用的是等价的(null).Id
FirstOrDefault
返回默认值(T)
如果序列为空,并且对于类默认值(T)
为空。谢谢-这正是我希望发生的:)当您看到类似以下内容时:FirstOrDefault()。SomeProperty
您可以轻松更改为First().SomeProperty
因为当找不到实体时,抛出将以任何方式发生。当您看到类似以下内容时:FirstOrDefault().SomeProperty
可以轻松更改为First()。SomeProperty
因为当找不到实体时,抛出将以任何方式发生。