Anonymous Type vs Named Class problem

P

Paolo

I've run into a problem trying to create a named class with a grouped
LINQ query and intermediate aggregations.

I created a class thus:

public class GroupedItem
{

string spacer = "\t"
public string CategoryDesc { get; set; }
public string SubCatDesc { get; set; }
public decimal Amount { get; set; }

public GroupedItem(string categoryDesc, string subCategoryDesc,
decimal amount)
{
CategoryDesc = c.C_Description,
SubCateDesc = s.S_Description,
Amount = trans.T_Amount
}

public string ToString(string decimalDisplayFormat)
{
return Category + spacer + SubCategory + spacer +
Amount.ToString(decimalDisplayFormat);
}
}

to use in the following LINQ query:

private void btnGroupedCategories_Click(object sender, EventArgs e)
{
var groupQuery =
from trans in dataSet.Transaction
from c in dataSet.Category where trans.T_Category == c.C_Id
from s in dataSet.SubCategory where trans.T_SubCategory ==
s.S_Id

select new GroupedItem
(
c.C_Description,
s.S_Description,
trans.T_Amount
)
into startGroup

group startGroup by new
{
startGroup.CategoryDesc,
startGroup.SubCatDesc
}
into secondGroup

select new
{
Category = secondGroup.Key.CategoryDesc,
SubCategory = secondGroup.Key.SubCatDesc,
Count = secondGroup.Count(),
Sum = secondGroup.Sum(s => s.Amount),
Mean = ( secondGroup.Sum(s =>
s.Amount))/(secondGroup.Count())
}
into thirdGroup

orderby thirdGroup.Category,
thirdGroup.SubCategory

select thirdGroup;

string headerText = "Column headers go here";
setRTBHeadings(headerText);

foreach (GroupedItem item in groupQuery)
{

richtxbxAnalysis.AppendText(item.ToString(decimalDisplayFormat) +
Environment.NewLine);
}
}

I am receiving an error regarding unable to convert anonymous type to
Grouped Item.

I'm assuming this is something to do with the

select new
{
Category = secondGroup.Key.CategoryDesc,
SubCategory = secondGroup.Key.SubCatDesc,
Count = secondGroup.Count(), <<<<<<<< problem??
Sum = secondGroup.Sum(s => s.Amount), <<<<<<<<
Mean = ( secondGroup.Sum(s =>
s.Amount))/(secondGroup.Count()) <<<<<<<<
}


I've got Category, SubCategory and Amount defined in my GroupedItem class
but I don't know how to deal with Count, Sum and Mean - I can't pass them as
parameters in the constructor since they don't exist at instantiation. I've
also not been able to include these in my ToString() method for the same
reason.

How do I solve this problem?
 
P

Paolo

Pete: I originally had a query based simply on an anonymous type (var) the
results of which were displayed in a Windows Richtextbox control. However I
could not format the output as I was limited to the 'vanilla' ToString()
method.

With Goran Andersson's help I created a named typed with a ToString() method
which allowed me to format output as I wished. This was a simple one table
query with no intermediate calculations or grouping so I could pass all of
the data items into the constructor for the type.

I continue to require formatted out put so I created another class
(GroupedItem) with a specific ToString() method. The query which is the
subject of this post has the added complication that when I have acquired the
data I require and grouped it into my 'secondGroup' I perform the Sum, Count
and Mean calculations on the result set. The output required is a summary by
SubCategory within Category where each summary line shows the Count (of
transactions in the subcategory) , Sum (of the decimal amounts for the
transactions in the subcategory) and Mean of the transactions' amount in the
subcategory.

The LINQ may well be iffy but it works as I want it in the anonymous type
version. I am looking for assistance on how to include the results of the
Count, Sum, and Mean calculations in the GroupedItem version and then to
format the output as I require.

I trust this at least gives you an idea of what I am trying to achieve.


Peter Duniho said:
[...]
I am receiving an error regarding unable to convert anonymous type to
Grouped Item.

I'm assuming this is something to do with the

select new
{
Category = secondGroup.Key.CategoryDesc,
SubCategory = secondGroup.Key.SubCatDesc,
Count = secondGroup.Count(), <<<<<<<< problem??
Sum = secondGroup.Sum(s => s.Amount), <<<<<<<<
Mean = ( secondGroup.Sum(s =>
s.Amount))/(secondGroup.Count()) <<<<<<<<
}

It only has something to do with that inasmuch as your "groupQuery"
variable winds up being an IEnumerable<T> where T is the anonymous type
you define in that "new { ... }" clause after the "select".

The whole thing looks a little iffy to me, but I'm no LINQ expert so I
might be misinterpreting the results of your complex query. Assuming the
query itself is actually correct, you'll need to enumerate the
"groupQuery" collection with a "var" variable, rather than a typed one,
and that will have properties as declared in your anonymous type, not
those found in GroupedItem.

If that's not sufficient to help you address your problem, you should post
a concise-but-complete code sample that reliably demonstrates the issue.
The code you posted wasn't even valid, even beyond the compiler error
you're asking about, never mind was it complete (i.e. compilable and
runnable without adding anything else).
I've got Category, SubCategory and Amount defined in my GroupedItem class
but I don't know how to deal with Count, Sum and Mean - I can't pass
them as
parameters in the constructor since they don't exist at instantiation.
I've
also not been able to include these in my ToString() method for the same
reason.

You should be more clear about what you're actually looking for help
with. The compiler error that you've asked about, can be addressed as I
state above. But, if you want the final collection to be of type
GroupedItem, you need to be more specific about what that collection would
look like and why it is if you don't want to do anything with the Count,
Sum, and Mean properties of the anonymous class why you are including them
in the first place.

Pete
 
P

Paolo

Pete: the basic issue is getting formatted outpurt to a Richtextbox. I was
advised to provide a specific ToString() method. I was advised that I could
not do that with an anonymous type and to develop a named class.

Which is what I was trying to do. I DON'T KNOW how to incorporate count,
sum, and mean which is why I posted requesting assistance. If there is
another way to achieve formatted output - other than the way I was advised -
then I'd be glad to hear it.

You say that "the code you posted wasn't correct". In what way was it not
correct? I admit that it might not be the most efficient or elegant LINQ (I
am still learning) but, as I mentioned earlier, in its original anonymous
type version it gave exactly the results I wanted - with the exception of
formatted out put ... which is where we started, I think.

Peter Duniho said:
[...]
The LINQ may well be iffy but it works as I want it in the anonymous type
version. I am looking for assistance on how to include the results of
the
Count, Sum, and Mean calculations in the GroupedItem version and then to
format the output as I require.

I trust this at least gives you an idea of what I am trying to achieve.

I'm sorry, but no. None of your explanation actually describes how it is
you intend for those three calculations to be correlated/used with your
named GroupedItem class. Why _would_ a single item contain aggregated
information such as the count, sum, and mean? How did you expect to apply
that in the code you posted?

Your reply mainly reiterates what the code you posted already said.
Unfortunately, the code you posted wasn't correct, nor did it provide a
complete picture of what you're actually trying to do. The reiteration of
that code doesn't seem to me to add anything substantial to the original
post.

Pete
 
Top