Guard against divide-by-0 in a LINQ groupby select statement
I have the following LINQ statement:
var result = CommisionDataContext.COMMISSIONS
.Where(c.PRODUCT == 'Computer')
.GroupBy(g => new
{
CostCenter = g.COST_CENTER,
Product = g.PRODUCT,
}
.Select(group开发者_JAVA技巧 => new
{
Revenue = group.Sum(p => p.REVENUE),
Volume = group.Sum(p => p.VOLUME),
Avg = group.Sum(p => p.REVENUE) / group.Sum(p => p.VOLUME),
});
How can I guard against the Divide by zero exception which could happen, and if it does I just want Avg to be equal to 0.
To avoid summing more than necessary, you should be able to do something like this (note that your code does not compile, however):
...
.Select(group => new
{
Revenue = group.Sum(p => p.REVENUE),
Volume = group.Sum(p => p.VOLUME)
})
.Select(item => new
{
item.Revenue,
item.Volume,
Avg = item.Volume == 0 ? 0 : item.Revenue / item.Volume
});
Be careful because C# Double can handle Infinity values, in fact if you try
var x = 5.0 / 0.0
you will find that x = Infinity (without Exception) and this is really different from 0! So, if you want your AVG = 0 be sure it's correct from a mathematical and representational point of view (for example I work with marketing formulas and charts and it's important to know if my AVG is a true 0 or an approximation to avoid wrong charts representation and misconception).
Anyway, this code avoids a Divide by zero Exception (you need to set AVG as Double) if you find useful the exact value of AVG operation taking care of the Infinity return value if the volumes sum is 0.
Avg = Convert.ToDouble(group.Sum(p => p.REVENUE)) / group.Sum(p => p.VOLUME))
Otherwise you can use the "check before" approach with a single evaluation.
var x = Convert.ToDouble(group.Sum(p => p.REVENUE)) / group.Sum(p => p.VOLUME));
Avg = Double.IsInfinity(x)? 0 : x;
Just replace
Avg = group.Sum(p => p.REVENUE) / group.Sum(p => p.VOLUME),
with
Avg = group.Sum(p => p.VOLUME) == 0
? 0
: group.Sum(p => p.REVENUE) / group.Sum(p => p.VOLUME),
精彩评论