2017-02-09 2 views
1

Betrachten Sie den folgenden Fall:Linq links kommen, wenn die Klasse auf der linken Seite des Gleichheits null sein kann

Klassen

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

Instanzen

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

Abfrage

Die Abfrage löst eine Ausnahme in der equals-Anweisung aus, wenn null ist.

Was ich erreichen möchte, ist dies: Wenn ist Null, sollte ein null Wert anstelle davon platziert werden; Es ist so, als wäre zugewiesen, aber Id ist null. Kann es gemacht werden?

EDIT: Ich muss C# 5.0 verwenden.

+1

Das ist genau das, was [C# null Konditionaloperator] (https : //msdn.microsoft.com/en-us/library/dn986595.aspx) ist für - 'on p? .NestedType.Id ist gleich m.Id' –

Antwort

1

Mit einer where(...) Klausel können Sie die NULL-Verweis Ausnahme werfen in Ihrem Fall verhindern und überprüfen, ob diese gewünschte Ergebnis für die Fälle produzieren:

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

ODER

Wenn Sie möchten, erhalten alle linksseitigen Werte immer, zum Beispiel in Ihrem Fall, wenn das Ergebnis etwa wie folgt aussehen sollte, können Sie Null-Conditional Operator in C# 6.0 +:

verwenden

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

ODER

Wenn wir es in C# 5 als kommentierte unten tun, dann können Sie tun:

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

Aber das wird die ganze Reihe eliminieren, wo' p.NestedType' ist Null. Ich möchte eigentlich, dass die Reihe erscheint - es ist schließlich eine linke Verbindung. – HeyJude

+0

Ich muss C# 5.0 verwenden – HeyJude

+0

@HeyJude Aktualisierte Antwort für C# 5. Hoffe, dass dir das hilft. –

Verwandte Themen