views:

746

answers:

4

Is there any way to convert a collection of objects into a single new object using LINQ?

I want to use this within another LINQ to SQL expression.

+3  A: 

The normal way would be to use one of the aggregation operators (Aggregate, Sum, Average etc), but it entirely depends on the type and what you want to do. What type are you interested in?

EDIT: Okay, so you want to concatenate strings... I don't think there's anything which will do that in LINQ to SQL itself. Options:

  • Write a stored proc or TVF to do it in SQL
  • Fetch the individual strings in LINQ to SQL and concatenate back on the client side
Jon Skeet
It's string, and I want to append using a separator string e.g. ", " or "<br/>".
mdresser
@ OP. Why not use StringBuilder if you're just appending strings?
Gishu
@Jon OT But could you take a look at question 926352.. can you tie up the loose ends in my understanding?
Gishu
+3  A: 

Why don't you use the string.Join itself?

string.Join("<br/>", collection.Select(e => e.TextProp).ToArray());
bruno conde
The problem is that I doubt that will be translated into SQL. Maybe it will - but I doubt it. If it works, I'm happy just to remove my answer entirely :)
Jon Skeet
After a quick test with linqpad I don't think this gets translated to SQL. If the OP needs this to be translated I think he should opt on a stored proc like you or Marc have suggested.
bruno conde
Dammit why didn't I see this. I built my own extension method to do this and everything.
Callum Rogers
+2  A: 

You can use the Aggregate method...

var myResults = (from myString in MyStrings
                 select myString)
                .Aggregate(string.Empty, (results, nextString) 
                   => string.Format("{0}<br />{1}", results, nextString));
Scott Ivey
A: 

Most of the solutions here are fairly inefficient if you have large numbers of values you want to concatonate. Also, they're not all that readable. If you are going to do this sort of thing frequently, then it's worth building your own extension method to do it. The implementation below allows you to do the equivalent of string.Join(", ", arrayOfStrings) where the arrayOfStrings can be an IEnumerable<T>, and separator can be any object at all. It allows you to do something like this:

var names = new [] { "Fred", "Barney", "Wilma", "Betty" };
var list = names
    .Where(n => n.Contains("e"))
    .Join(", ");

Two things I like about this are:

  1. It's very readable in a LINQ context.
  2. It's fairly efficient because it uses StringBuilder and avoids evaluating the enumeration twice which is important in a database scenario (L2S, L2E, or L2Nh).
public static string Join<TItem,TSep>( 
    this IEnumerable<TItem> enuml, 
    TSep                    separator) 
{ 
    if (null == enuml) return string.Empty; 

    var sb = new StringBuilder(); 

    using (var enumr = enuml.GetEnumerator()) 
    { 
        if (null != enumr && enumr.MoveNext()) 
        { 
            sb.Append(enumr.Current); 
            while (enumr.MoveNext()) 
            { 
                sb.Append(separator).Append(enumr.Current); 
            } 
        } 
    } 

    return sb.ToString(); 
}
Damian Powell