如何使用linq将对象扩展为基本属性

假设我有以下课程:

public class StudentTeacher { public Student Student {get; set;} public Teacher Teacher {get; set;} public int OverlappingClasses {get; set;} } 

现在,在我的代码中,我有一个对象列表。

 List studentTeacher = GetStudentTeachers(); 

现在,我需要选择所有属性作为属性而不是对象。

所以,例如,我可以这样做: studentTeacher.Select(x=>x.Student) ,它将返回一个对象列表(IEnumerable)。

但是当我选择多个属性时,即studentTeacher.Select(x => new {x.Student,x.Teacher})。ToList()返回类型是IEnumerable {Anonymous {Student, Teacher}}

如何,而不是这个复杂的匿名类型,我可以有一个简单的匿名类型,只有属性。 (因此,它将是Anonymous{StudentID, StudentName, StudentLastName, TeacherID, TeahcerName, TeacherLastName, etc.}

一种方法是通过显式指定select子句中的所有属性,但在我的特定用例中,我在每个对象中有> 30个属性,并且属性总数> 100。)

我想这就是你要做的事情:

  public class Student { public int StudentId { get; set; } = 1; public string StudentName { get; set; } = "Name"; } public class Teacher { public int TeacherId { get; set; } = 666; public string TeacherName { get; set; } = "TeacherName"; } public class StudentTeacher { public Student Student { get; } = new Student(); public Teacher Teacher { get; } = new Teacher(); } public static dynamic GetAnonType(Student student, Teacher teacher) { var propertyNamesAndPropertiesStudent = student.GetType().GetProperties().Select(item => Tuple.Create($"{nameof(Student)}{item.Name}", item.GetMethod.Invoke(student, null))); var propertyNamesAndPropertiesTeacher = teacher.GetType().GetProperties().Select(item => Tuple.Create($"{nameof(Teacher)}{item.Name}", item.GetMethod.Invoke(teacher, null))); dynamic sampleObject = new ExpandoObject(); foreach(var propertyNamePropertyValuePair in propertyNamesAndPropertiesStudent) { ((IDictionary)sampleObject).Add(propertyNamePropertyValuePair.Item1, propertyNamePropertyValuePair.Item2); } foreach(var propertyNamePropertyValuePair in propertyNamesAndPropertiesTeacher) { ((IDictionary)sampleObject).Add(propertyNamePropertyValuePair.Item1, propertyNamePropertyValuePair.Item2); } return sampleObject; } 

您可以这样调用:

  var studentTeachers = new List {new StudentTeacher()}; var anonTypes = studentTeachers.Select(item => GetAnonType(item.Student, item.Teacher)); 

anonTypes将是一个包含成员StudentId,StudentName,TeacherId,TeacherName的匿名类型的可枚举。 这应该扩展到更大的对象。

 studentTeacher.Select(x=> new {x.Student.StudentID, x.Student.StudentName, x.Student.StudentLastName, x.Teacher.TeacherID, x.Teacher.TeahcerName, x.Teacher.TeacherLastName, etc.}) 

它将使用属性名称作为对象内的名称,即Student = x.Student.StudentID您也可以直接分配例如

 studentTeacher.Select(x=> new { StudentID = x.Student.StudentID, x.Student.StudentName, x.Student.StudentLastName, x.Teacher.TeacherID, x.Teacher.TeahcerName, x.Teacher.TeacherLastName, etc.}) 

如果你有很多属性,为什么不选择全class?

 IEnumerable studentTeachers = GetStudentTeachers(); IEnumerable femaleTeachers = studentTeachers .Where(teacher => teacher.IsFemale); 

现在您不必提及所有属性。 这也适用于连接:

 var TeachersWithTheirStudents = studentTeachers.GroupJoin(students, teacher => teacher.Id, student => student.TeacherId, (teacher, students) => new { Teacher = teacher, HisStudents = students, } 

用语言:小组加入TeachersStudents的集合。 从每位Teacher那里获取Id 。 让所有具有与此Id相同的TeacherId Students ,从这位Teacher和他的所有Students制作一个Anonymous对象,其中包含属性TeacherHisStudents