7

IQueryable枚举以下内容时会发生异常:

from record in dataContext.SomeTable
select Convert.ToDecimal(record.nullableDecimalColumn);

错误是InvalidOperationException

不能将 null 值分配给类型为 decimal 的成员,该类型是不可为 null 的值类型

for 的文档Convert.ToDecimal说它转换null0,所以看起来它应该可以正常工作。

4

2 回答 2

8

如果你这样写查询

tot_vat_amt = _pd.Where(x => x.VAT == 4m).Sum(x =>x.amount)

用。。。来代替

tot_vat_amt = _pd.Where(x => x.VAT == 4m).Sum(x =>(double?)x.amount)

希望对你有帮助

于 2015-11-20T11:02:57.417 回答
4

LINQ to SQL 没有ToDecimal等效地翻译该方法;它不能容忍NULL。我通过使用GetValueOrDefault而不是解决了这个问题Convert.ToDecimal

from record in dataContext.SomeTable
select record.nullableDecimalColumn.GetValueOrDefault();

这导致生成了正确的 SQL,因此不再发生异常。

这是我对为什么会发生这种情况的理解。LINQ to SQL 和实体框架提供面值语义翻译而不是字面翻译。在此示例中,Convert.ToX直接转换为SQLCONVERTCAST在 SQL 中。这是 SQL 的等效翻译,但不是字面意思,因为它不包括.NET如何Convert.ToX操作的详细信息。具体来说,.NET 将nulls 转换为默认值。

这是代码没有表达其作者(不是我)真正想要做的事实的症状,即将nulls 转换为默认值,而不是在数据类型之间进行转换。

在我看来,这也是IQueryable一种泄漏和不可靠的抽象的症状。我个人认为最好不要一开始就使用它,而是使用设计得更好的东西,比如普通/流畅的 API。我认为IQueryable完全违反了接口隔离原则,因为它允许使用无限范围的查询,尽管只支持有限的子集。

于 2013-09-12T06:31:04.707 回答