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

时间:2017-08-25 04:43:35

标签: c# .net linq

我们说我有以下课程:

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

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

List<StudentTeacher> studentTeacher = GetStudentTeachers();   

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

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

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

如何使用仅具有属性的简单匿名类型,而不是这种复杂的匿名类型。 (因此,它将是Anonymous{StudentID, StudentName, StudentLastName, TeacherID, TeahcerName, TeacherLastName, etc.}

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

3 个答案:

答案 0 :(得分:1)

我认为这是你正在尝试做的事情:

    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<string, object>)sampleObject).Add(propertyNamePropertyValuePair.Item1, propertyNamePropertyValuePair.Item2);
        }

        foreach(var propertyNamePropertyValuePair in propertyNamesAndPropertiesTeacher)
        {
            ((IDictionary<string, object>)sampleObject).Add(propertyNamePropertyValuePair.Item1, propertyNamePropertyValuePair.Item2);
        }

        return sampleObject;
    }

您可以这样称呼:

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

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

答案 1 :(得分:0)

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.})

答案 2 :(得分:0)

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

IEnumerable<StudentTeacher> studentTeachers = GetStudentTeachers();
IEnumerable<StudentTeacher> 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。从这个Students获取TeacherId等于此Id Teacher的所有Students,并使其所有Teacher制作一个包含属性HisStudents的匿名对象, public class OnResetListener implements View.OnClickListener { private ViewHolder oHolder; OnResetListener(ViewHolder holder) { oHolder = holder; } @Override public void onClick(View v) { if(oHolder instanceof FolderVH){ ((FolderVH) oHolder).viewPager.setCurrentItem(0, true); } else if(oHolder instanceof NoteVH) { ((NoteVH) oHolder).viewPager.setCurrentItem(0, true); } else if(oHolder instanceof CheckListVH) { ((CheckListVH) oHolder).viewPager.setCurrentItem(0, true); } } }