简体   繁体   English

转换为int32时发生异常

[英]exception when converting to int32

When executing this code, I receive an error on the last line. 执行此代码时,我在最后一行收到错误。 How should this be rewritten to avoid the exception? 应该如何重写以避免异常?

   var q = from i in dbconnect.tblMaterialTenderGroups
                join b in dbconnect.tblMaterials on i.materialId equals b.materialId
                join f in dbconnect.tblFactoryRequests on b.requestId equals f.requestId
                where i.MaterialGroupId == materialGroupId && f.propertyFactoryCenteralId.Contains(facName)
                select b;
        int ab= q.Count();

        int? sum = q.Sum(g => Convert.ToInt32(g.requestAmount));

The execption is 执行是

System.InvalidOperationException: The null value cannot be assigned to a member with type System.Int32 which is a non-nullable value type. System.InvalidOperationException:无法将null值分配给类型为System.Int32的成员,该类型是不可为null的值类型。

g.requestAmount is of type nvarchar(100) . g.requestAmount的类型为nvarchar(100)

Such exception happens, when EF tries to materialize query result. 当EF尝试实现查询结果时,会发生此类异常。 Some of resulting fields contains null, but the entity property (or anonymous type, when using projections with Select ), which is mapped to that field, is int instead of int? 一些结果字段包含null,但是映射到该字段的实体属性(或匿名类型,当使用带有Select投影时)是int而不是int? .

If you'll look carefully at stack trace, you'll get an entity, which should declare int? 如果仔细看一下堆栈跟踪,就会得到一个实体,该实体应声明为int? property. 属性。

Add casting to nullable integer: 将强制转换添加到可为空的整数:

 int? sum = q.Sum(g => (int?)Convert.ToInt32(g.requestAmount));

Interesing thing here is that exactly same query will be generated whether you add casting or not. 有趣的是,无论是否添加强制转换,都会生成完全相同的查询。 Simplified it looks like: 简化后的样子:

SELECT SUM([t1].[value]) AS [value]
FROM (
    SELECT CONVERT(Int,[t0].[requestAmount]) AS [value], [t0].[Id]
    FROM [dbo].[People] AS [t0]
    ) AS [t1]
WHERE ...

It returns integer value when you have some rows to sum. 当您要累加一些行时,它将返回整数值。 But what if there is nothing to sum (ie all rows was filtered out)? 但是,如果没有要累加的内容(即,所有行都被过滤掉了)怎么办? Database query will return NULL in that case. 在这种情况下,数据库查询将返回NULL

Here we should understand what Linq to SQL does with returned value. 在这里,我们应该了解Linq to SQL用返回值做什么。 There is two different Sum extensions exist for IQueryable<T> : IQueryable<T>有两种不同的Sum扩展名:

int Sum<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, int>> selector)
Nullable<int> Sum<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, Nullable<int>>> selector)

First one tries to assign query results to integer value (and that gives you exception). 第一个尝试将查询结果分配给整数值(这会给您带来例外)。 Second one tries to assign query results to nullable integer. 第二个尝试将查询结果分配给可为空的整数。 So, you simply need to call second Sum method, which is called when you cast selector result to nullable type. 因此,您只需要调用第二个Sum方法,即可将选择器结果转换为可为null的类型时调用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM