1

I have a LINQ statement that use average on grade, but the problem is that sometimes

grade gets like 3.777777 displayed, but I would like it to be 3.7 how can I truncate it in my linq statement?

this is my LINQ statement:

public List<CoreValueAndAverageGrade> GetAverageGradeForAllCoreValues2()
{
    var answers = db.GoalCardQuestionAnswer
        .Where(answer => answer.Grade.HasValue
            && (answer.SelectedQuestion.Question is CoreValueQuestion
                && (answer.SelectedQuestion.Question as CoreValueQuestion).SubjectType.Ignored_Statistic == false));
    var groupedByCoreValue = answers.GroupBy(answer => (answer.SelectedQuestion.Question as CoreValueQuestion).CoreValue);

    return groupedByCoreValue
        .OrderBy(group => group.Key.Name)
        .Select(group => new CoreValueAndAverageGrade
        {
            CoreValue = group.Key,
            AverageGrade = group.Any() ? group.Average(answer => answer.Grade.Value) : 0
        }).ToList();

Maby its possible to do it inside the controller in my action method?

var averageGrades = OfficeStatisticRepository.GetAverageGradeForAllCoreValues2();

var dataItems = (averageGrades.Select(averageGrade => averageGrade.AverageGrade).ToArray()); // here
tereško
  • 58,060
  • 25
  • 98
  • 150
Obsivus
  • 8,231
  • 13
  • 52
  • 97
  • 3
    well you have [`decimal.Round`](http://msdn.microsoft.com/en-us/library/6be1edhb%28v=vs.90%29) does that work for you ? – V4Vendetta May 21 '12 at 09:31
  • check-->http://stackoverflow.com/questions/1381345/linq-to-sql-math-round-problem – rt2800 May 21 '12 at 09:33
  • 1
    Check out [`Enumerable.OfType`](http://msdn.microsoft.com/en-us/library/bb360913.aspx) - It will make your first two bits of code a little more readable. – Merlyn Morgan-Graham May 21 '12 at 09:35
  • 1
    I think you mean truncate rather than round. 3.777777 rounded to one decimal place would be 3.8. – Richard Ev May 21 '12 at 10:04

1 Answers1

2

You have three options here.

1) Round in the Linq query using Math.Truncate Just like you would use Average or Aggregate. as part of the Linq->SQL translation.

...
... ? group.Average(answer => Math.Truncate(10 * answer.Grade.Value) / 10) : 0M
...

Funny that the docs mention a System.Math.Truncate(decimal, int) method, but that it doesn't actually exist... Luckily you can just multiply and round. This will work fine for Decimals, but if your grade is a Double, it might cause new rounding issues because of the division.

2) Round the values in your Linq query after calling ToList using decimal.Round (be sure to pick the right rounding direction, for grades you won't want to use bankers rounding.

 var groupedByCureValue = answers.GroupBy....ToList();
 /* then in the next query use Math.Truncate or Math.Round as you 
    would otherwise, you can now use MidPointRounding if you want to 
    no sql translation is done as this is all executed in memory, 
    so you're free to use any framework method available to you. */

3) Keep the values unchanged and only display the rounded value in your UI using a display format such as F1 on the textbox/label/binding you're using to display the value. How you'll set this up is dependent on the display framework you're using. This will not combine values if there's a 3.77 and a 3.76 in the group.

jessehouwing
  • 106,458
  • 22
  • 256
  • 341