考虑以下情况:
类
public class Nested
{
public Nested(int id){ Id = id; }
public int? Id {get; set;}
}
public class Pair
{
public Nested NestedType {get; set;}
public string Name {get; set;}
}
public class Match
{
public int? Id {get; set;}
public string Name {get; set;}
}
实例
var p1 = new Pair();
p1.NestedType = new Nested(1);
p1.Name = "a";
var p2 = new Pair();
p2.NestedType = null;
p2.Name = "b";
var p3 = new Pair();
p3.NestedType = new Nested(3);
p3.Name = "c";
List<Pair> pairs = new List<Pair>() {p1, p2, p3};
var m1 = new Match();
m1.Id = 1;
m1.Name = "AA";
var m2 = new Match();
m2.Id = null;
m2.Name = "BB";
var m3 = new Match();
m3.Id = 3;
m3.Name = "CC";
List<Match> matches = new List<Match>(){m1, m2, m3};
查询
var query = from p in pairs
join m in matches on p.NestedType.Id equals m.Id into pm
from m in pm.DefaultIfEmpty()
select new
{
PairName = p.Name,
MatchId = m != null ? m.Id : null
MatchName = m != null ? m.Name : null
};
当equals
为空时,查询将在p.NestedType
语句行上抛出异常。
我想要实现的目标是:当p.NestedType
为空时,应放置null
值而不是它;就像分配了p.NestedType
但其Id
为空。可以吗?
答案 0 :(得分:1)
使用where(...)
子句,您可以防止在您的案例中抛出空引用异常,并检查这是否会为您的案例产生所需的结果:
var query = from p in pairs
where p.NestedType!=null //Notice the where condition added
join m in matches on p.NestedType.Id equals m.Id into pm
from m in pm.DefaultIfEmpty()
select new
{
PairName = p.Name,
MatchId = m != null ? m.Id : null,
MatchName = m != null ? m.Name : null
};
或强>
如果您想要始终获取所有左侧值,例如,如果结果看起来像下面这样,您可以使用Null-Conditional Operator in C# 6.0 +:
var query = from p in pairs
join m in matches on p?.NestedType?.Id equals m.Id into pm //Notice Null-Conditional operator: p?.NestedType?.Id
from m in pm.DefaultIfEmpty()
select new
{
PairName = p.Name,
MatchId = m != null ? m.Id : null,
MatchName = m != null ? m.Name : null
};
或强>
如果我们需要在下面评论的C#5中进行,您可以这样做:
var query = from p in pairs
let nestedTypeId = (p != null && p.NestedType != null) ? p.NestedType.Id : null
join m in matches on nestedTypeId equals m.Id into pm
from m in pm.DefaultIfEmpty()
select new
{
PairName = p.Name,
MatchId = m != null ? m.Id : null,
MatchName = m != null ? m.Name : null
};