2016-10-19 1 views
1

Ich habe eine List<Data> wo DatenListe <Object> auf Hierarchie

ist
public class Data 
{ 
    public string SchoolId {get; set;} 
    public string SchoolName {get; set;} 
    public string TeacherId {get; set;} 
    public string TeacherName {get; set;} 
} 

Die Liste Wohnung ist:

SchoolId SchoolName  TeacherId  TeacherName 
1   X    1    Mr X 
1   X    2    Mrs Y 
2   Y    3    Mr Z 
2   Y    1    Mr X 

Also im Grunde ein Lehrer zu vielen Schulen gehören.

Wie kann ich die flache Liste oben in eine List<School>

public class School 
{ 
    public School() 
    { 
      this.Teachers = new List<Teacher>(); 
    } 
    public string SchoolId { get; set; } 
    public string SchoolName { get; set; } 
    public List<Teacher> Teachers {get; set;} 
} 


public class Teacher 
{ 
    public string TeacherId { get; set; } 
    public string TeacherName { get; set; } 
} 

Antwort

2

konvertieren Wenn das Linq-Objekte, verwenden Sie diesen Code

var result = list.GroupBy(x=>new {x.SchoolId, x.SchoolName}) 
.Select(x=> 
{ 
    var s = new School(); 
    s.SchoolId = x.Key.SchoolId; 
    s.SchoolName = x.Key.SchoolName; 
    s.Teachers.AddRange(x.Select(
     y => new Teacher 
     { 
      TeacherId = y.TeacherId, 
      TeacherName = y.TeacherName 
     } 
    )); 

    return s; 
}); 

Bitte beachten Sie, dass obige Code in zweifacher Ausfertigung Teacher führen Instanz sogar unter Teacher mit demselben Id.

+0

's.Teachers' könnte null sein – dotctor

+1

@dotctor Es sollte nicht für frisches Objekt, weil es in' School' Konstruktor initialisiert wird. –

+0

Sie haben Recht. Sehen Sie sich den Konstruktor von 'School' an. – dotctor

2

Die Reihenfolge dieses Ansatzes ist O (n^2) und es gibt keine Lehrerinstanzen.

var schools = data 
    .GroupBy(x => x.SchoolId) 
    .Select(group => new School() 
    { 
     SchoolId = group.Key, 
     SchoolName = group.First().SchoolName, 
     Teachers = data.Where(x => x.SchoolId == group.Key) 
      .Select(x => new Teacher() 
      { 
       TeacherId = x.TeacherId, 
       TeacherName = x.TeacherName 
      }) 
      .ToList() 
    }) 
    .ToList(); 

Wenn Sie Instanzen von Lehrer teilen möchten, dann können Sie verwenden diese

var teachersById = data 
    .GroupBy(x => x.TeacherId) 
    .Select(group => new Teacher() 
    { 
     TeacherId = group.Key, 
     TeacherName = group.First().TeacherName 
    }) 
    .ToDictionary(x => x.TeacherId); 

var schools = data 
    .GroupBy(x => x.SchoolId) 
    .Select(group => new School() 
    { 
     SchoolId = group.Key, 
     SchoolName = group.First().SchoolName, 
     Teachers = teachersById 
      .Where(kv => data 
       .Where(x => x.SchoolId == group.Key) 
       .Select(x => x.TeacherId) 
       .Contains(kv.Key) 
      ) 
      .Select(x => x.Value) 
      .ToList() 
    }) 
    .ToList(); 
+0

Sollte die zweite nicht einfach 'Teachers = group.Select (x => teachersById [x.TeacherId]) sein. ToList()' (um den Vorteil des Wörterbuchs zu nutzen) –

0
List<Data> dataList = new List<Data>(); 

IEnumerable<School> schools = from d in dataList 
           group d by new { SchoolId = d.SchoolId, SchoolName = d.SchoolName } into groupSchool 
           select new School { SchoolId = groupSchool.Key.SchoolId, SchoolName = groupSchool.Key.SchoolName, Teachers =new List<Teacher>(groupSchool.Select(x => new Teacher { TeacherId = x.TeacherId, TeacherName = x.TeacherName })) }; 
0

item.SchoolIdNote: es Pseudo-Kode (für kurze Code benutzte ich Konstrukteuren mit Parametern statt Verwendung von Eigenschaften)

List<Data> data = //....; 
Dictionary<string, Teacher> teachers = new Dictionary<string, Teacher>(); 
Dictionary<string, School> schools = new Dictionary<string, School>(); 
foreach (var item in data) 
{ 
    if (item.TeacherId not in teachers) 
     teachers.add(item.TeacherId, new Teacher(item.TeacherId, item.TeacherName)); 
} 
foreach (var item in data) 
{ 
    if (item.SchoolId not in schools) 
     schools.add(item.SchoolId , item.SchoolName, new School(item.SchoolId , teachers[item.SchoolId])); 
} 
List<School> gen_schools =  // get values from schools; 

PS Tatsächlich verwenden Sie eine falsche Darstellung Ihrer Datenbank (Sie sollten Lehrer von Schulen in zwei verschiedene Tabellen trennen).