Sam*_*Sam 5 .net c# exception linq-to-sql
IQueryable枚举以下内容时发生异常:
from record in dataContext.SomeTable
select Convert.ToDecimal(record.nullableDecimalColumn);
Run Code Online (Sandbox Code Playgroud)
错误是InvalidOperationException:
无法将null值分配给类型为decimal的成员,该成员是非可空值类型
Convert.ToDecimal说它转换null为的文档0,所以它看起来应该正常工作.
小智 7
如果你这样写了Query
tot_vat_amt = _pd.Where(x => x.VAT == 4m).Sum(x =>x.amount)
Run Code Online (Sandbox Code Playgroud)
用...来代替
tot_vat_amt = _pd.Where(x => x.VAT == 4m).Sum(x =>(double?)x.amount)
Run Code Online (Sandbox Code Playgroud)
希望对你有帮助
LINQ to SQL 并没有ToDecimal等效地转换该方法;它不能容忍NULL。我通过使用GetValueOrDefault而不是解决了这个问题Convert.ToDecimal:
from record in dataContext.SomeTable
select record.nullableDecimalColumn.GetValueOrDefault();
Run Code Online (Sandbox Code Playgroud)
这导致生成正确的 SQL,因此不再发生异常。
这是我对为什么会发生这种情况的理解。LINQ to SQL 和实体框架提供面值语义翻译而不是字面翻译。在此示例中,Convert.ToX直接翻译为SQLCONVERT或CASTSQL。这是 SQL 的等效翻译,但不是字面意思,因为它不包括.NET如何操作的详细信息Convert.ToX。具体来说,.NET 将nulls 转换为默认值。
这是一个事实的症状,即代码没有表达其作者(不是我)真正想要做的事情,即将nulls 转换为默认值,而不是在数据类型之间进行转换。
IQueryable在我看来,这也是抽象漏洞和不可靠的症状。我个人认为最好一开始就不要使用它,而是使用设计得更好的东西,比如普通/流畅的 API。我认为IQueryable完全违反了接口隔离原则,因为尽管只支持有限的子集,但它允许使用无限范围的查询。