转换为int32时的异常

时间:2013-12-04 19:05:09

标签: c# linq-to-sql

执行此代码时,我在最后行收到错误。如何重写以避免异常?

   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));

执行是

  

System.InvalidOperationException:无法将null值分配给a       System.Int32类型的成员,它是一个不可为空的值类型。

g.requestAmount的类型为nvarchar(100)

2 个答案:

答案 0 :(得分:1)

当EF尝试实现查询结果时,会发生此类异常。某些结果字段包含null,但映射到该字段的实体属性(或使用Select的投影时的匿名类型)为int而不是int?

如果您仔细查看堆栈跟踪,您将获得一个实体,该实体应声明int?属性。

答案 1 :(得分:0)

将强制转换添加到可以为null的整数:

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

这里有兴趣的是,无论你是否添加了强制转换,都会生成完全相同的查询。简化它看起来像:

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

当您要求总和的某些行时,它会返回整数值。但如果没有什么可以总结(即所有行都被过滤掉了)怎么办?在这种情况下,数据库查询将返回NULL

在这里,我们应该了解Linq to SQL对返回值的作用。 Sum存在两种不同的IQueryable<T>扩展名:

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)

首先尝试将查询结果分配给整数值(这会给你带来异常)。第二个尝试将查询结果分配给可空整数。因此,您只需要调用第二个Sum方法,该方法在将选择器结果转换为可空类型时调用。