mardi 1 mai 2018

GroupBy multiple properties in nested objects dynamically

Problem

I have a list of objects that needs to be grouped by multiple properties during run-time.

public class ParentClass {
    public int ID { get; set; }
    public string Name { get; set; }
    public NestedClassOne NestedOne { get; set; }
    public NestedClassThree NestedThree { get; set; }
}

public class NestedClassOne {
    public string Make { get; set; }
    public string Model { get; set; }
    public NestedClassTwo NestedTwo { get; set; }
}

public class NestedClassTwo {
    public string Data { get; set; }
}

public class NestedClassThree {
    public string Name { get; set; }
}

var data = new List<ParentClass> {
    new ParentClass {
        ID = 1,
        Name = "Car";
        NestedOne = new NestedClassOne {
            Make = "Toyota";
            Model = "Corolla";
            NestedTwo = new NestedClassTwo {
                Data = "Auto"
            };
        };
        NestedThree = new NestedClassThree {
            Name = "Smith";
        };
    },
    new ParentClass {
        ID = 2,
        Name = "Car";
        NestedOne = new NestedClassOne {
            Make = "Nissan";
            Model = "GTR";
            NestedTwo = new NestedClassTwo {
                Data = "Manual"
            };
        };
        NestedThree = new NestedClassThree {
            Name = "Taylor";
        };
    },
    new ParentClass {
        ID = 3,
        Name = "Car";
        NestedOne = new NestedClassOne {
            Make = "Toyota";
            Model = "Corolla";
            NestedTwo = new NestedClassTwo {
                Data = "Manual"
            };
        };
        NestedThree = new NestedClassThree {
            Name = "Jack";
        };
    },
    new ParentClass {
        ID = 4,
        Name = "Jeep";
        NestedOne = new NestedClassOne {
            Make = "Nissan";
            Model = "X-Trail";
            NestedTwo = new NestedClassTwo {
                Data = "Auto"
            };
        };
        NestedThree = new NestedClassThree {
            Name = "Jack";
        };
    },
    new ParentClass {
        ID = 5,
        Name = "Jeep";
        NestedOne = new NestedClassOne {
            Make = "Toyota";
            Model = "Vantage";
            NestedTwo = new NestedClassTwo {
                Data = "Manual"
            };
        };
        NestedThree = new NestedClassThree {
            Name = "Shawna";
        };
    }
};

I get a list of property names like "Name", "NestedOne.NestedTwo.Data", "NestedOne.Make". So using this list of property names, the code needs to group the above list of data, so that functions such as 'Count' can be executed on them.

Approach

I've tried to use Reflection to obtain the property values and create a new ExpandoObject which would then be passed into 'GroupBy' method. However, it seems that ExpandoObjects are not supported.

Therefore, researching into it, I ran into an amazing solution here on this link.

GroupBy(params string[] fields) | Code Review StackOverFlow

This pretty much, solves my problem as long as the properties are on the parent object itself. It doesn't support generating the Expressions, for the nested properties such as "NestedOne.NestedTwo.Data", "NestedOne.Make".

Desired output would be similar to this.

Name    |  NestedOne.Make    |  NestedOne.NestedTwo.Data    |  Count
========|====================|==============================|=========
Car     |  Toyota            |  Manual                      |  27  
Car     |  Nissan            |  Manual                      |  09  
Jeep    |  Toyota            |  Auto                        |  15  
Jeep    |  Nissan            |  Auto                        |  36  

Request

I am quite familiar with C-Sharp. However, I am a novice when it comes to 'Expression' building. Is my approach to this problem correct? Is there an easier way to achieve this functionality? Can anyone help me out? I would appreciate any help at this point, regardless how small it is.

Thank you everyone





Aucun commentaire:

Enregistrer un commentaire