执行此代码时,我在最后行收到错误。如何重写以避免异常?
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)
。
答案 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
方法,该方法在将选择器结果转换为可空类型时调用。