I'm building an executive summary report that uses a single group. I only need a summary, so the Details section is hidden, and I only populate the group header and footer with aggregate data (see the reportdesigner.png attachment). I have brute-forced a solution by manually computing my summary values, the first page of the resulting report is in the reportcapture.png attachment.
The problem is that I will be doing a similar report that is organized the same way, but given it will be generating charts from the details rather than just computing summary information, my current code-behind brute-force solution likely won't work as well. And I'm thinking that I shouldn't have had to brute-force it in the first place.
The background is that I have a set of Entity-Data Framework objects projected from a simple SQL database. The two tables in question are a table of Circuits (mapped to Circuit objects in C#), and a master table of logged voltage/power entries. Each power entry was measured by a meter (and has a relation to yet another table of Meters) and was of course measured from a specific Circuit.
EDF has projected an ObjectSet of Circuits, which is my DataSource for the report. Within each Circuit object, EDF made me a Navigation Property called LoggedACMeterDatas. I group the report based on the Circuit.id (the table key). So each group header has as its "focus" a specific Circuit. Hence the "Fields.Name" and "Fields.Circuit.Location.Name" resolve to the correct thing on a single Circuit object.
The problem is now I want to access the LoggedACMeterDatas (an EntityCollection that is projected from a Foreign-Key Relation), in order to fill in some summary information in the report. For example, the "Period Start" and "Period End" are the earliest and latest timestamp in the LoggedACMeterDatas . The power summary fields are each an average of a specific field across all the LoggedACMeterDatas for the current Circuit in the grouping.
I would have liked to build an Expression along the lines of Min(Fields.LoggedACMeterDatas.Timestamp) for the Period Start. After all, specifying Fields.Name in the group header (which in the context of the entire report is a collection, but in the context of the group is a scalar) seems to do the right thing. But I could find no way to do that with field that is an EntityCollection. Similarly, for the power summaries, something like Avg(Fields.LoggedACMeterDatas.VoltagePhase1) to get an average of all the VoltagePhase1 members of the sub-collection. In short, I can specify Fields.LoggedACMeterDatas in an Expression, but there seems to be precious little I can do with it.
So my brute-force was to add the following properties to the Circuit class, essentially doing the above in code-behind, where I can do something useful with the LoggedACMeterDatas member:
So as I said above, the brute-force workaround is ok in this case, but it seems like I should have been able to do all this in the realm of the report. Secondly, I don't see how I'm going to be able to build a Chart instead of a table of scalar averages---I'm going to need some mechanism by which I can hand off the EntityCollection to the Chart. But I don't see how I can do that.
Any help appreciated...
The problem is that I will be doing a similar report that is organized the same way, but given it will be generating charts from the details rather than just computing summary information, my current code-behind brute-force solution likely won't work as well. And I'm thinking that I shouldn't have had to brute-force it in the first place.
The background is that I have a set of Entity-Data Framework objects projected from a simple SQL database. The two tables in question are a table of Circuits (mapped to Circuit objects in C#), and a master table of logged voltage/power entries. Each power entry was measured by a meter (and has a relation to yet another table of Meters) and was of course measured from a specific Circuit.
EDF has projected an ObjectSet of Circuits, which is my DataSource for the report. Within each Circuit object, EDF made me a Navigation Property called LoggedACMeterDatas. I group the report based on the Circuit.id (the table key). So each group header has as its "focus" a specific Circuit. Hence the "Fields.Name" and "Fields.Circuit.Location.Name" resolve to the correct thing on a single Circuit object.
The problem is now I want to access the LoggedACMeterDatas (an EntityCollection that is projected from a Foreign-Key Relation), in order to fill in some summary information in the report. For example, the "Period Start" and "Period End" are the earliest and latest timestamp in the LoggedACMeterDatas . The power summary fields are each an average of a specific field across all the LoggedACMeterDatas for the current Circuit in the grouping.
I would have liked to build an Expression along the lines of Min(Fields.LoggedACMeterDatas.Timestamp) for the Period Start. After all, specifying Fields.Name in the group header (which in the context of the entire report is a collection, but in the context of the group is a scalar) seems to do the right thing. But I could find no way to do that with field that is an EntityCollection. Similarly, for the power summaries, something like Avg(Fields.LoggedACMeterDatas.VoltagePhase1) to get an average of all the VoltagePhase1 members of the sub-collection. In short, I can specify Fields.LoggedACMeterDatas in an Expression, but there seems to be precious little I can do with it.
So my brute-force was to add the following properties to the Circuit class, essentially doing the above in code-behind, where I can do something useful with the LoggedACMeterDatas member:
public
Double AverageVoltagePhase1
{
get
{
return
(from entry
in
LoggedACMeterDatas select entry.VoltagePhase1).Average(); } }
public
Double AverageVoltagePhase2
{
get
{
return
(from entry
in
LoggedACMeterDatas where entry.VoltagePhase2.HasValue select entry.VoltagePhase2.Value).Average(); } }
public
Double AverageVoltagePhase3
{
get
{
return
(from entry
in
LoggedACMeterDatas where entry.VoltagePhase3.HasValue select entry.VoltagePhase3.Value).Average(); } }
public
Double AverageCurrentPhase1
{
get
{
return
(from entry
in
LoggedACMeterDatas select entry.CurrentPhase1).Average(); } }
public
Double AverageCurrentPhase2
{
get
{
return
(from entry
in
LoggedACMeterDatas where entry.CurrentPhase2.HasValue select entry.CurrentPhase2.Value).Average(); } }
public
Double AverageCurrentPhase3
{
get
{
return
(from entry
in
LoggedACMeterDatas where entry.CurrentPhase3.HasValue select entry.CurrentPhase3.Value).Average(); } }
public
Double AverageWattsPhase1
{
get
{
return
(from entry
in
LoggedACMeterDatas select entry.WattsPhase1).Average(); } }
public
Double AverageWattsPhase2
{
get
{
return
(from entry
in
LoggedACMeterDatas select entry.WattsPhase2).Average(); } }
public
Double AverageWattsPhase3
{
get
{
return
(from entry
in
LoggedACMeterDatas select entry.WattsPhase3).Average(); } }
public
Double AveragePowerFactor
{
get
{
return
(from entry
in
LoggedACMeterDatas select entry.AvgPowerFactorAllPhases).Average(); } }
public
DateTime StartPeriod
{
get
{
return
(from entry
in
LoggedACMeterDatas orderby entry.Timestamp select entry.Timestamp).First(); } }
public
DateTime EndPeriod
{
get
{
return
(from entry
in
LoggedACMeterDatas orderby entry.Timestamp select entry.Timestamp).Last(); } }
So as I said above, the brute-force workaround is ok in this case, but it seems like I should have been able to do all this in the realm of the report. Secondly, I don't see how I'm going to be able to build a Chart instead of a table of scalar averages---I'm going to need some mechanism by which I can hand off the EntityCollection to the Chart. But I don't see how I can do that.
Any help appreciated...