0

Environment: ASP.net Core 2 Web API Project.

I have a query that queries a Database and returns a Model with lots of properties. Some properties are unique to each record (eg. Name) and others are connected with multiple records (eg. Category, Type, etc).

At the end of the day I need to work out a summary of the Categories returned, and a count of the records for each category. Generally, I would do this SQL, but I can't in this instance.

I worked out that I can do it with LINQ:

Eg:

var results = GetSearch(....); //Thing that gets all the results from the database.

var catSummary = results.GroupBy(c => c.Category).ToList();

Which is great, however, I have about 6 of these to do. So I thought: I'll make a list:

List<string> FilterableAttributes = new List<string>
    {
            "Category",
            "Type",
            "Town"
    }; 

Then loop over the Model like so:

SearchResults searchresults = new SearchResults(); //This is the Model used in the results.
foreach (PropertyDescriptor prop in TypeDescriptor.GetProperties(searchresults))
{
    var match = FilterableAttributes.FirstOrDefault(stringToCheck => stringToCheck.Contains(prop.Name));
    if (match != null)
    {
        var summary = results.GroupBy(c => c.XXXXXXX).ToList(); //Here is where I'm stuck.
    }
}

Which should work, I just have no idea how to pass the Property from the Model into the GroupBy statement. I know I can get the name of the Property via 'prop.Name' But I can't seem to work out how to use it.

I've also tried to do this way:

var summary = from r in results 
              group r by r.XXXXXX into g //Unknown how to make this work
              select new { Name = g.Key, Count = g.Count() };

(This is probably the way I should go, as it makes the next part easier).

This section of code is probably the most requested part of the API, so speed is important. (I keep reading how 'slow' reflection is)

C# is new to me, my background is in Python.

Thoughts, comments, ideas? I realise I might be going about this all wrong, hence I provided some details of what I'm trying to achieve overall, not just the technical question.

1 Answer 1

1

If the variable 'results' is an user defined type, then you can use Linq to objects like below.

var summary = results.GroupBy(c => c.GetType().GetProperty(category).GetValue(c, null))

If it is a database object then this can be achieved by a simple if - else condition like below.

SearchResults searchresults = new SearchResults(); 
foreach (PropertyDescriptor prop in TypeDescriptor.GetProperties(searchresults))
{
    var match = FilterableAttributes.FirstOrDefault(stringToCheck => stringToCheck.Contains(prop.Name));
    if (match != null)
    {
        var summary = new List(); 
        if(prop.Name == "prop1") // Place prop1 in a static constants variable
          {
        summary = results.GroupBy(c => c.yourProperty1).ToList(); 
          }
        else if(prop.Name == "prop2")
          {
              // go on
          }
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks! Upon further research, it appears that I'm hitting a programming style limitation. In Python I'd prefer to write much less code, minimum to no duplication of code, but C# strongly typed compiler doesn't work this way. It forces/encourages the programmer to write more code so that it know's exactly what is happening at compile time. Whereas Python does everything at runtime, so there isn't the performance benefit.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.