Linq. Aggregate

S

shapper

Hello,

I have the following Linq query:

var q = (from p in database.Posts
join pt in database.PostsTags on p.PostID equals
pt.PostID
join t in database.Tags on pt.TagID equals t.TagID
group t by p into pt
select new PostPaper {
Post = pt.Key,
Tags = pt.ToList(),
TagsCSV = pt.Aggregate((a, b) => a.Name + ", " +
b.Name)
}).ToPagedList(page.HasValue ? page.Value - 1 : 0,
ListPageSize);

I am getting an error on the aggregate function:
Cannot implicitly convert type 'string' to 'BonsAlunos.Models.Tag'

Basically, what I am trying to do is build TagsCSV with the Name
property of all tags from Tags list separated by commas ... any idea
of how to do this?

Thanks,
Miguel
 
J

Jeroen Mostert

shapper said:
I have the following Linq query:

var q = (from p in database.Posts
join pt in database.PostsTags on p.PostID equals
pt.PostID
join t in database.Tags on pt.TagID equals t.TagID
group t by p into pt
select new PostPaper {
Post = pt.Key,
Tags = pt.ToList(),
TagsCSV = pt.Aggregate((a, b) => a.Name + ", " +
b.Name)
}).ToPagedList(page.HasValue ? page.Value - 1 : 0,
ListPageSize);

I am getting an error on the aggregate function:
Cannot implicitly convert type 'string' to 'BonsAlunos.Models.Tag'
While you can use .Aggregate() for this, it's more trouble than it's worth
(removing the final, unnecessary comma can't be done with an inline
expression). Just use string.Join():

TagsCSV = string.Join(", ", pt.Select(t => t.Name).ToArray())

And I'm getting a strong sense of deja vu here, because you used this exact
expression in a post made not 24 hours ago in this newsgroup. It was good
then, it's still good now. :)
 
S

shapper

While you can use .Aggregate() for this, it's more trouble than it's worth
(removing the final, unnecessary comma can't be done with an inline
expression). Just use string.Join():

   TagsCSV = string.Join(", ", pt.Select(t => t.Name).ToArray())

And I'm getting a strong sense of deja vu here, because you used this exact
expression in a post made not 24 hours ago in this newsgroup. It was good
then, it's still good now. :)

Yes, you are right!

But I saw something like this using Aggregate so I though it was a
better way to do this.

So I will keep String.Join.

Thanks,
Miguel
 
J

Jeroen Mostert

shapper said:
Yes, you are right!

But I saw something like this using Aggregate so I though it was a
better way to do this.
Actually, it depends. If you expect that there will be a great number of
PostPaper objects and .TagsCSV will only be evaluated sporadically, then
using .Aggregate() may win out as its execution is deferred (unlike
String.Join). This would be pretty unusual, though.

On the other hand, if you expect .TagsCSV to be evaluated for every item,
then .Aggregate() is certainly not better here. It essentially amounts to
concatenating strings in a loop, which is what we're always told not to do
(as it produces a lot of string garbage). Although creating the array with
names has overhead too, it still scales better.

Using an explicit StringBuilder is more efficient still, but that's hardly
worth it.
 
S

shapper

Actually, it depends. If you expect that there will be a great number of
PostPaper objects and .TagsCSV will only be evaluated sporadically, then
using .Aggregate() may win out as its execution is deferred (unlike
String.Join). This would be pretty unusual, though.

On the other hand, if you expect .TagsCSV to be evaluated for every item,
then .Aggregate() is certainly not better here. It essentially amounts to
concatenating strings in a loop, which is what we're always told not to do
(as it produces a lot of string garbage). Although creating the array with
names has overhead too, it still scales better.

Using an explicit StringBuilder is more efficient still, but that's hardly
worth it.

From your description String.Join seems the best solution.

Thank You,
Miguel
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

Linq. Please, need help. 1
Linq. Avoid Joins 2
Linq. String 5
Filter 1
Condition 2
Linq 1
Linq > Group 2
Local Sequence cannot be used ... except the Contains() operator 4

Top