2017-02-09 21 views
1

考虑以下情况:LINQ的左连接时,在等号的左边的类可以是空

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

p.NestedType为空时,查询将在equals语句行上抛出异常。

我想达到的是:当p.NestedType为空时,应该放置一个null值而不是它;这好像是p.NestedType已分配,但其Id为空。可以做到吗?编辑:我不得不使用C#5.0。

+1

这正是[C#空条件操作符(HTTPS ://msdn.microsoft.com/en-us/library/dn986595.aspx)用于 - 'on p?.NestedType.Id等于m.Id' –

回答

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

OR

如果你想获得所有的左侧值总是,例如,在你的情况下,如果结果应该看起来像下面那样,你可以使用Null-Conditional Operator in C# 6.0 +

enter image description here

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

OR

如果我们需要做的是在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 
      }; 
+0

但是,这将消除“p.NestedType”所在的整行空值。我真的希望这一行出现 - 毕竟这是一个左连接。 – HeyJude

+0

我必须使用C#5.0 – HeyJude

+0

@HeyJude为C#5更新了答案。希望能帮到你。 –