我有一个Linq2Sql查询,如下所示:
var data = from d in dc.GAMEs
where (d.GAMEDATE + d.GAMETIME.Value.TimeOfDay) >= DateTime.Now
&& d.GAMESTAT == 'O' && d.GAMETYPE == 0 select d;
Resharper以蓝色突出显示“d.GAMETIME.Value.TimeOfDay”并告诉我这是一个可能的System.InvalidOperationException。虽然我知道如果它是C#代码,引用Value而不检查它是否有值,我不确定Linq查询是否正确。
生成的实际SQL看起来很可怕,并且让我想要烧掉我的眼睛,但我看不出任何看起来像是空引用的东西。我可以放心地忽略这个吗?
(暂时忽略其他问题,例如是否返回预期结果)
编辑:
进一步思考,我可以看到上面的内容如何在LinqToObjects查询中引起异常,可能还有其他类型(XML?)。所以,是的,我认为Resharper只是安全。
答案 0 :(得分:2)
在处理表达式树时(如此LINQ to SQL查询),它完全取决于所使用的LINQ提供程序(在您的情况下是LINQ to SQL)。因此,Resharper(几乎)不可能对您的查询说任何有用的内容。我认为它只是将此代码解释为普通的C#代理。我会说可以安全地忽略,但也许可以为下一个开发者添加评论。
答案 1 :(得分:0)
如果没有看到数据模式,我的猜测是GAMETIME
是Nullable<DateTime>
- 即映射到DB中的datetime / time字段可以为null。 Resharper只是给你一个静态分析警告,你引用Nullable<T>.Value
而不检查它是否有值。
您可以这样重写查询:
var data = from d in dc.GAMEs
where (d.GAMEDATE + (d.GAMETIME.HasValue ? d.GAMETIME.TimeOfDay : new TimeSpan())) >= DateTime.Now
&& d.GAMESTAT == 'O' && d.GAMETYPE == 0 select d;
当GAMETIME
为NULL时,上述查询将使用TimeSpan为0。
考虑到GAMEDATE
是一个不可为空的数据库字段而GAMETIME
是可以为空的,我建议您也使GAMETIME不可为空。这样两个字段是一致的,不需要额外的逻辑来处理NULL
值。
编辑我刚刚确认,尝试拨打Nullable<T>.Value
确实会引发InvalidOperationException
,而不是NullReferenceException
。
来自horse's mouth(粗暴是我的):
这两个基本成员 可以为Nullable的结构是HasValue 和Value属性。如果是HasValue Nullable对象的属性是 是的,对象的值可以是 使用Value属性访问。 如果 HasValue属性为false,即 对象的值是未定义的 试图访问价值 财产投掷 出现InvalidOperationException 强>