为什么'Submissions.Where(s =>(false && s.Status == Convert.ToInt16("")))'引发FormatException?

dba*_*baw 3 c# linq

我认为这个查询非常简单,但是它提出了一个FormatException("输入字符串的格式不正确"):

Submissions.Where(s => (false && s.Status == Convert.ToInt16("")))
Run Code Online (Sandbox Code Playgroud)

(当然,在我的代码中,另一个计算结果为'false'的表达式位于'&&'之前)

那么为什么'&&'之后的部分被评估,因为第一部分总是假的,总表达式永远不能评估为true

情况特别奇怪,因为只有Convert.ToInt16("")部分似乎引发异常 - 我原始查询的其他部分或多或少相同的结构,如

Submissions.Where(s => (false && s.SubmissionDate <= DateTime.Now))
Run Code Online (Sandbox Code Playgroud)

正确评估.

Jer*_*ine 6

正如其他人所指出的那样,LINQ to SQL代码在作为针对数据库的SQL代码运行之前被拆分为表达式树.由于SQL不一定遵循与C#相同的短路布尔规则,因此可能会解析表达式代码的右侧,以便可以构造SQL.

来自MSDN:

C#指定基于逻辑运算符&&和||的操作数的词序的短路语义.另一方面,SQL针对基于集合的查询,因此为优化程序提供了更多自由来决定执行顺序.

至于为什么你用这个代码得到一个异常,Convert.ToInt16("")总是会抛出那个异常,因为没有办法将空字符串转换为整数.您的另一个示例不会尝试无效转换,因此它运行没有问题.


Mar*_*ell 5

如果SubmissionsIQueryable<T>,那么这不是常规的C#委托,而是表达式树.一些代码(LINQ提供者)必须将这个树拉开并理解它 - 所以如果你在表达式中有奇怪的东西,那么期望奇数输出.