2016-05-11 2 views
1

Ich habe zwei SQL-Tabellen in meiner Datenbank. Hier werden sie als C# Klassen vertreten:Wie kann ich einen LINQ-Select erstellen, der ein untergeordnetes Objekt wie einen SQL-Outer-Join enthält?

public class Topic 
{ 
    public Topic() 
    { 
     this.SubTopics = new HashSet<SubTopic>(); 
    } 

    public int TopicId { get; set; } 
    public string Name { get; set; } 
    public int Number { get; set; } 
    public virtual ICollection<SubTopic> SubTopics { get; set; } 
} 

public class SubTopic 
{ 
    public int SubTopicId { get; set; } 
    public int TopicId { get; set; } 
    public string Name { get; set; } 
    public virtual Topic Topic { get; set; } 
} 

ich diesen Code erstellt eine einfache Liste zu erhalten:

var result = db.SubTopics 
      .Select(s => new 
      { 
       TopicId = s.TopicId, 
       SubTopicId = s.SubTopicId, 
       TopicName = s.Topic.Name, 
       SubTopicName = s.Name 
      }) 
      .ToListAsync(); 

Ergebnis hier aber es funktioniert nur, wenn ich ein Unterthema für jedes Thema haben:

Topic1 SubTopic1 abc def 
Topic1 SubTopic2 ghi jkl 
Topic2 SubTopic3 mno pqr 
Topic3 SubTopic4 stu vwx 
Topic3 SubTopic5 xxx yyy 

ich möchte ein Ergebnis erhalten, wie dies der Suche nach den Fällen, in denen ich für jedes Thema keine Subtopic haben:

Topic1 SubTopic1 abc def 
Topic1 SubTopic2 ghi jkl 
Topic2 null  mno null 
Topic3 SubTopic4 stu vwx 
Topic3 SubTopic5 xxx yyy 

oder ein Ergebnis wie dieses, wenn gab es keine untergeordneten Themen überhaupt:

Topic1 null  abc null 
Topic2 null  mno null 
Topic3 null  stu null 

Kann mir jemand einen Rat geben, wie ich dies mit LINQ bekommen konnte. Ich nehme an, ich zum ersten Ziel wie diese benötigen würde:

var result = db.Topics 

Aber ich bin nicht sicher, wie ich in den untergeordneten Themen hinzufügen und habe es für den Fall arbeiten, wo es manchmal keine passenden Unterthemen sind.

+0

Mögliches Duplikat von [LEFT OUTER JOIN in LINQ] (http://stackoverflow.com/questions/3404975/left-outer-join-in-linq) – BenR

Antwort

3

Sie müssen von Topics starten und DefaultIfEmpty für SubTopics verwenden. In Ihrem Fall ist es ganz einfach, weil Sie eine richtige Navigationseigenschaften haben:

var result = (from t in db.Topics 
       from s in t.SubTopics.DefaultIfEmpty() 
       select new 
       { 
        TopicId = t.TopicId, 
        SubTopicId = (int?)s.SubTopicId, 
        TopicName = t.Name, 
        SubTopicName = s.Name 
       }) 
      .ToListAsync(); 
+0

ein einfacher Weg;) – octavioccl

+0

@octavioccl yeah :) –

2

Nun Sie eine äußere Verknüpfung kann:

var query=from t in db.Topics 
      join st in db.SubTopics on t.TopicId equals st.TopicId into g 
      from s in g.DefaultIfEmtpy 
      select new { 
         TopicId = t.TopicId, 
         SubTopicId = s.SubTopicId, 
         TopicName = t.Name, 
         SubTopicName = s.Name 
        }; 
+1

Sie don 'n t muss "s" für null übrigens überprüfen. – Evk

0

Diese auf Ihre Frage keine Antwort, aber vielleicht ist es eine Antwort dein Problem Nicht selten ist das wirklich, was Sie wollen:

var result=db.Topics 
    .Include(t=>t.SubTopics) 
    .ToListAsync(); 

Mit diesem können Sie durch Ihre Themen laufen, und das Kind Themen wie folgt aus:

foreach(var topic in result) 
{ 
    Console.WriteLine("Topic:"+topic.Name); 
    foreach(var subtopic in topic.SubTopics) 
    { 
    Console.WriteLine(" SubTopic:"+subtopic.Name"); 
    } 
} 

, die die folgende Ausgabe geben würde:

Topic: Topic1 
    SubTopic: SubTopic1 
    SubTopic: SubTopic2 
Topic: Topic2 
Topic: Topic3 
    SubTopic: SubTopic4 
    SubTopic: SubTopic5 

Dies ist sehr nützlich, wenn Sie eine Baumstruktur wie für Navigation/Menüsystem erstellen, oder müssen Untersummen, etc.

Verwandte Themen