我有linq查询,左外连接两个表。我发现如果一个字段的值返回null,那么我将收到一条错误消息:
"转换为值类型' System.Int32'失败,因为具体化值为null。结果类型的通用参数或查询必须使用可空类型。"
我在下面复制了我的linq:
var SrvRef = from s in db.SrvHeads
join r in db.Referrants on s.svhReferrer equals r.refID into r_join
from r in r_join.DefaultIfEmpty()
where s.svhAccID == accId &&
s.svhHeadCnt == HeadId
select new
{
s.svhBalance,
r.refID
};
bool FBeenPaid = SrvRef.FirstOrDefault().svhBalance == 0M; //this causes error
如何解决此问题?
答案 0 :(得分:8)
我对你得到的那种错误感到有些惊讶,但是你需要考虑到结果为空的可能性两个:
r
可以为null。 (如果您不希望在r_join
匹配s
时没有元素时匹配,则不应使用左外连接。FirstOrDefault()
,如果null
为空,则会返回SrvRef
。所以乍一看它应该是这样的:
var query = from s in db.SrvHeads
join r in db.Referrants on s.svhReferrer equals r.refID into r_join
from r in r_join.DefaultIfEmpty()
where s.svhAccID == accId && s.svhHeadCnt == HeadId
select new
{
s.svhBalance,
refId = r == null ? 0 : r.refID // Adjust to the appropriate type of refID
};
var result = query.FirstOrDefault();
bool beenPaid = result != null && result.svhBalance == 0m;
使用C#6,您可以将底部的两行更改为:
bool beenPaid = query.FirstOrDefault()?.svhBalance == 0m ?? false;
说完了:
refId
- 为什么要将其包含在结果中?你有什么理由不在查询中做整件事吗?类似的东西:
var paid = db.SrvHeads
.Where(s => s.svhAccID == accId && s.svhHeadCnt == HeadId)
.Any(s => db.Refererrants.Any(r => s.svhReferrer == r.refID
&& s.svhBalance == 0m);
..但只是为了你想要的精确语义。
答案 1 :(得分:1)
我认为导致错误的是svhBalance是一个int32值类型,并且您正在访问SrvRef.FirstOrDefault()返回的空值。 请尝试以下行,并告诉我它是否对您有帮助。
如果svhBalance是int值类型
var SrvRefObj = SrvRef.FirstOrDefault(); bool FBeenPaid =(((SrvRefObj!= null)&&(SrvRefObj.svhBalance != null))?(SrvRefObj.svhBalance == 0):( false))
否则,如果是小数值类型
var SrvRefObj = SrvRef.FirstOrDefault(); bool FBeenPaid =(((SrvRefObj!= null)&&(SrvRefObj.svhBalance != null))?(SrvRefObj.svhBalance == 0M):( false))
答案 2 :(得分:0)
我有一个类似的问题。
原因:您使用的是r_join.DefaultIfEmpty()
中“ r ”中的内容。左外部联接不能使用相同的别名。
解决方案::在DefaultIfEmpty()
情况下,请使用其他别名。例如:rEmpty
我修改了以下查询及其工作方式。
var SrvRef = from s in db.SrvHeads
join r in db.Referrants on s.svhReferrer equals r.refID into r_join
from rEmpty in r_join.DefaultIfEmpty()
where s.svhAccID == accId &&
s.svhHeadCnt == HeadId
select new
{
s.svhBalance,
refID = rEmpty == null ? 0 : rEmpty.refID
};