2013-11-15 10 views
6

के पदानुक्रमित सेट निम्नलिखित मॉडल की एक सूची को देखते हुए वापस जाने के लिएLINQ पुनरावर्ती पूछताछ समूहों

public class Team 
{ 
    public int TeamId { get; set; } 
    public int ParentTeamId { get; set; } 
} 

मैं एक पुनरावर्ती LINQ क्वेरी जो मुझे एक पदानुक्रम है कि इस

तरह लग रहा है पुनः प्राप्त करने के लिए सक्षम हो जाएगा लिखने के लिए कोशिश कर रहा हूँ
Team 
    ChildTeams 
Team 
    Team 
     ChildTeams 

मैंने कई दृष्टिकोणों की कोशिश की है और कई समान प्रश्न देखे हैं, लेकिन उनमें से कोई भी विशेष रूप से समस्या को हल करने में मेरी सहायता नहीं करता है। नवीनतम प्रयास मैंने कोशिश की इन पंक्तियों के साथ चला गया:

private class TeamGrouping 
{ 
    public int? ParentTeamId { get; set; } 
    public IEnumerable<Team> ChildTeams { get; set; } 
    public IEnumerable<TeamGrouping> Grouping { get; set; } 
} 

private IEnumerable<TeamGrouping> ToGrouping(IEnumerable<Team> teams) 
{ 
    return teams.GroupBy(t => t.ParentTeamId, (parentTeam, childTeams) => new TeamGrouping {ParentTeamId = parentTeam, ChildTeams = childTeams}); 
} 

private IEnumerable<TeamGrouping> ToGrouping(IEnumerable<TeamGrouping> teams) 
{ 
    return teams.GroupBy(t => t.ParentTeamId, (parentTeam, childTeams) => new TeamGrouping{ParentTeamId = parentTeam, Grouping = childTeams}); 
} 

मैं ToGrouping(IEnumerable<TeamGrouping>) में पहले ToGrouping(IEnumerable<Team>) और फिर बाद में लौट आए समूहों में टीमों की सूची से होकर गुजरेगा, लेकिन यह गलत परिणाम उत्पादन कर रहा है।

किसी के पास कोई सलाह या विचार है? एक पुनरावर्ती समारोह

private IEnumerable<Team> BuildTeams(IEnumerable<Team> allTeams, 
                int? parentId) 
    { 
     var teamTree = new List<Team>(); 
     var childTeams = allTeams.Where(o => o.ParentId == parentId).ToList(); 

     foreach (var team in childTeams) 
     { 
      var t = new Team(); 
      var children = BuildTeams(allTeams, team.TeamID); 
      t.ChildTeams = children; 
      teamTree.Add(t); 
     } 

     return teamTree ; 
    } 

पहली कॉल माता-पिता के लिए एक null गुजरता

public class Team 
{ 
    public ParentId {get;set;} 
    public IEnumerable<Team> ChildTeams{get;set;} 
} 

फिर, और खींच लेंगे:

+0

तो आप टीमों के एक फ्लैट संग्रह के साथ शुरू कर रहे हैं, और आप एक पेड़ बनाना चाहते हैं? मुझे लगता है कि आपको यहां केवल LINQ से अधिक की आवश्यकता होगी (हालांकि मुझे गलत साबित होने में बहुत दिलचस्पी होगी)। जैसे ही आप टीमों के अपने संग्रह को फिर से शुरू करते हैं, आपको एक पेड़ बनाने की आवश्यकता होगी, IGrouping एस का संग्रह नहीं। –

+0

क्षमा करें, हाँ ने उल्लेख किया होगा कि यह टीमों की एक विस्तृत सूची है। – ChrisO

उत्तर

4

तो सबसे पहले, आपके TeamGrouping वास्तव में इसकी अपेक्षा से थोड़ा अधिक जटिल है।

public class TeamNode 
{ 
    public Team Value { get; set; } 
    public IEnumerable<TeamNode> Children { get; set; } 
} 

अगला हम टीमों के हमारे अनुक्रम लेने के लिए और हर एक के लिए एक नोड पैदा हो जाएगी: सभी इसकी आवश्यकता Team वस्तु और बच्चों के लिए खुद का एक क्रम है। फिर हम उनके माता-पिता आईडी द्वारा समूहित करने के लिए ToLookup का उपयोग करेंगे। (GroupBy का आपका उपयोग बहुत करीब है, लेकिन ToLookup आसान होगा।) अंततः हम प्रत्येक नोड के बच्चों को उस नोड के लुकअप वैल्यू के रूप में सेट कर सकते हैं (ध्यान दें कि ILookup एक रिक्त अनुक्रम वापस कर देगा यदि कुंजी नहीं है मौजूद है, इसलिए हमारी पत्तियों को पूरी तरह से संभाला जाएगा)। इसे खत्म करने के लिए हम null की मूल आईडी के साथ सभी नोड्स को देखकर सभी शीर्ष स्तर नोड्स को वापस कर सकते हैं।

public static IEnumerable<TeamNode> CreateTree(IEnumerable<Team> allTeams) 
{ 
    var allNodes = allTeams.Select(team => new TeamNode() { Value = team }) 
     .ToList(); 
    var lookup = allNodes.ToLookup(team => team.Value.ParentTeamId); 
    foreach (var node in allNodes) 
     node.Children = lookup[node.Value.TeamId]; 
    return lookup[null]; 
} 
1

सबसे पहले आप इस तरह एक वस्तु की आवश्यकता होगी, इसलिए टीम वस्तु हो सकता है सभी टीमें जिनके पास शून्य माता-पिता हैं :), हालांकि मुझे लगता है कि आपकी टीमों के पास माता-पिता के लिए शून्य नहीं है, इसलिए सुनिश्चित नहीं है कि आप वर्तमान में शीर्ष स्तर की पहचान कैसे करते हैं?

+0

यह अच्छी तरह से काम करता है, एक चीज जो मुझे नहीं मिलती है वह है कि आप नई टीम ऑब्जेक्ट क्यों बनाते हैं, आपको हर जगह शून्य गुण मिलेंगे, आप अभी तक 'टीम' ऑब्जेक्ट क्यों नहीं पारित करते हैं? – Martin

संबंधित मुद्दे