I have a database procedure that based on what data is available, will give me a grouped yearly summary. With my test instance I'm running, currently my data matches something similar
--------------------------------------------
|Month |Id |BehaviorName |Count |
--------------------------------------------
|1 |NULL| |0 |
--------------------------------------------
|2 |NULL| |0 |
--------------------------------------------
|3 |NULL| |0 |
--------------------------------------------
|4 |NULL| |0 |
--------------------------------------------
|5 |NULL| |0 |
--------------------------------------------
|6 |4 |Name1 |2 |
--------------------------------------------
|7 |4 |Name1 |5 |
--------------------------------------------
|7 |3 |NameElse |7 |
--------------------------------------------
|8 |NULL| |0 |
--------------------------------------------
|9 |NULL| |0 |
--------------------------------------------
|10 |NULL| |0 |
--------------------------------------------
|11 |NULL| |0 |
--------------------------------------------
|12 |NULL| |0 |
--------------------------------------------
This is a very simple result set but the data can be any more or less complicated. The data outputted here is going to be used in conjunction with the Telerik RadChart control for graphing purposes. Essentially what I need to do is take the result set above, and mirror it depending on how many instances of the specified ID occur so that it can be plotted as a separate series
So for instance BehaviorName titled Name1 would have it's own result set like
--------------------------------------------
|Month |Id |BehaviorName |Count |
--------------------------------------------
|1 |NULL| |0 |
--------------------------------------------
|2 |NULL| |0 |
--------------------------------------------
|3 |NULL| |0 |
--------------------------------------------
|4 |NULL| |0 |
--------------------------------------------
|5 |NULL| |0 |
--------------------------------------------
|6 |4 |Name1 |2 |
--------------------------------------------
|7 |4 |Name1 |5 |
--------------------------------------------
|8 |NULL| |0 |
--------------------------------------------
|9 |NULL| |0 |
--------------------------------------------
|10 |NULL| |0 |
--------------------------------------------
|11 |NULL| |0 |
--------------------------------------------
|12 |NULL| |0 |
--------------------------------------------
and BehaviorName titled NameElse would have it's own result set like
--------------------------------------------
|Month |Id |BehaviorName |Count |
--------------------------------------------
|1 |NULL| |0 |
--------------------------------------------
|2 |NULL| |0 |
--------------------------------------------
|3 |NULL| |0 |
--------------------------------------------
|4 |NULL| |0 |
--------------------------------------------
|5 |NULL| |0 |
--------------------------------------------
|6 |NULL| |0 |
--------------------------------------------
|7 |3 |NameElse |7 |
--------------------------------------------
|8 |NULL| |0 |
--------------------------------------------
|9 |NULL| |0 |
--------------------------------------------
|10 |NULL| |0 |
--------------------------------------------
|11 |NULL| |0 |
--------------------------------------------
|12 |NULL| |0 |
--------------------------------------------
I've decided in my application to take the single result set and try to split it into separate groupings via LINQ. My question is what would be the best approach for this?
var series = from occurence in fetched.YearlyTotals.Tables[0].AsEnumerable()
group occurence by g.Field<int>("TargetedBehaviorId") into occurences
select new
{
Behavior = occurences.Key,
Occurences = from o in occurences
select new
{
Month = o.Field<int>("Month"),
TargetedBehaviorId = o.Field<int>("TargetedBehaviorId"),
BehaviorName = o.Field<string>("BehaviorName"),
Count = o.Field<int>("Count")
}
};
Currently this will disregard any null fields, but I need to include every month within the series for each unique row that would match the result sets above. Currently this LINQ statement only gives me the 3 rows with data.
Also if there is an easier way that this can be accomplished on the SQL end, I wouldn't be opposed to working with that either.
Update:
I ended up using a combination of a few of the techniques mentioned in this question. I created a class specifically for creating my chart series items just for the sake of clarity
private class OccurrenceItem
{
public int TargetedBehaviorId { get; set; }
public int Month { get; set; }
public int Count { get; set; }
public string BehaviorName { get; set; }
public OccurrenceItem()
{
}
}
//Gets a list of all the months that are returne from the query
//Always returns all 12 months
int[] months = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
var currentBehaviors = from behaviors in fetched.TargetedBehaviors
select behaviors;
var emptySet = (from month in months
from behavior in currentBehaviors
select new OccurrenceItem
{
Month = month,
TargetedBehaviorId = behavior.AssignedBehaviorId,
BehaviorName = behavior.Behavior,
Count = 0
}).ToList();
var occurences = (from o in fetched.YearlyTotals.Tables[0].AsEnumerable()
select new OccurrenceItem {
Month = o.Field<int>("Month"),
TargetedBehaviorId = o.Field<int>("TargetedBehaviorId"),
BehaviorName = o.Field<string>("BehaviorName"),
Count = o.Field<int>("Count")
}).ToList();
var merged = occurences.Union(emptySet)
.GroupBy(x => new {
x.Month,
x.TargetedBehaviorId,
x.BehaviorName,
}).Select(x => new OccurrenceItem {
Month = x.Key.Month,
TargetedBehaviorId = x.Key.TargetedBehaviorId,
BehaviorName = x.Key.BehaviorName,
Count = (from y in x
select y.Count).Sum()
}).OrderBy(x => x.Month);
All of these statements combined get me a List<OccurenceItem>
which I can then separate out into separate series based on the TargetedBehaviorId
and add as my chart series