2016-10-19 3 views
1

J'ai un List<Data> où les données estListe <Object> à la hiérarchie

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

La liste est plat:

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

Donc, fondamentalement, un enseignant peut appartenir à plusieurs écoles.

Comment puis-je convertir la liste plate ci-dessus dans un 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; } 
} 

Répondre

2

Si tel est Linq à des objets, utilisez ce 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; 
}); 

S'il vous plaît noter que code ci-dessus entraînera en double exemplaire Teacher instance même parmi Teacher avec le même Id.

+0

's.Teachers' pourrait être nul – dotctor

+1

@dotctor Il ne devrait pas pour objet frais car il est initialisé dans le constructeur' School'. –

+0

Vous avez raison. Juste voir le constructeur de 'School'. – dotctor

2

L'ordre de cette approche est O (n^2) et elle ne partage pas les instances d'enseignant.

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(); 

Si vous souhaitez partager des cas d'enseignants, alors vous pouvez utiliser cette

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

La seconde ne devrait-elle pas être simple? Teachers = group.Select (x => teachersById [x.TeacherId]). ToList() '(pour profiter du dictionnaire) –

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: il est pseudo-code (pour le code bref je constructeurs avec des paramètres à la place utilisation de Propriétés)

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 En fait, vous utilisez une mauvaise représentation de votre base de données (vous devez séparer les enseignants des écoles en deux tables différentes).