learning - select in linq
Use LINQ para concatenar mĂșltiples filas en una sola fila(propiedad CSV) (6)
Ese es el operador GroupBy. ¿Estás usando LINQ para objetos?
Aquí hay un ejemplo:
using System;
using System.Collections.Generic;
using System.Linq;
public class Test
{
static void Main()
{
var users = new[]
{
new { User="Bob", Hobby="Football" },
new { User="Bob", Hobby="Golf" },
new { User="Bob", Hobby="Tennis" },
new { User="Sue", Hobby="Sleeping" },
new { User="Sue", Hobby="Drinking" },
};
var groupedUsers = users.GroupBy(user => user.User);
foreach (var group in groupedUsers)
{
Console.WriteLine("{0}: ", group.Key);
foreach (var entry in group)
{
Console.WriteLine(" {0}", entry.Hobby);
}
}
}
}
Eso es lo que hace la agrupación, ¿puedes manejar el resto tú mismo?
Estoy buscando el equivalente de LINQ al LIST de Sybase () o al group_concat de MySQL ()
Se convertirá:
User Hobby
--------------
Bob Football
Bob Golf
Bob Tennis
Sue Sleeping
Sue Drinking
A:
User Hobby
--------------
Bob Football, Golf, Tennis
Sue Sleeping, Drinking
Mira si esta solución te ayuda:
List<User> users = new List<User>()
{
new User {Name = "Bob", Hobby = "Football" },
new User {Name = "Bob", Hobby = "Golf"},
new User {Name = "Bob", Hobby = "Tennis"},
new User {Name = "Sue", Hobby = "Sleeping"},
new User {Name = "Sue", Hobby = "Drinking"}
};
var groupedUsers = from u in users
group u by u.Name into g
select new
{
Name = g.First<User>().Name,
Hobby = g.Select(u => u.Hobby)
};
foreach (var user in groupedUsers)
{
Console.WriteLine("Name: {0}", user.Name);
foreach (var hobby in user.Hobby)
{
Console.WriteLine("Hobby: {0}", hobby);
}
}
O bien podemos hacer lo siguiente
var users = new[]
{
new { User="Bob", Hobby="Football" },
new { User="Bob", Hobby="Golf" },
new { User="Bob", Hobby="Tennis" },
new { User="Sue", Hobby="Sleeping" },
new { User="Sue", Hobby="Drinking" },
};
var userList = users.ToList();
var ug = (from user in users
group user by user.User into groupedUserList
select new { user = groupedUserList.Key, hobby = groupedUserList.Select(g =>g.Hobby)});
var ug2 = (from groupeduser in ug
select new{ groupeduser.user, hobby =string.Join(",", groupeduser.hobby)});
Para hacerlo en un Linq Statement. No hay manera de recomendar el código, pero muestra que podría hacerse.
var groupedUsers = from user in users
group user by user.User into userGroup
select new
{
User = userGroup.Key,
userHobies =
userGroup.Aggregate((a, b) =>
new { User = a.User, Hobby = (a.Hobby + ", " + b.Hobby) }).Hobby
}
;
foreach (var x in groupedUsers)
{
Debug.WriteLine(String.Format("{0} {1}", x.User, x.userHobies));
}
con _concat
aspecto de su pregunta, usando:
static class EnumerableExtensions
{
public static String AsJoined( this IEnumerable<String> enumerable )
{
return AsJoined( enumerable, "," );
}
public static String AsJoined( this IEnumerable<String> enumerable, String separator )
{
return String.Join( separator, enumerable.ToArray() );
}
}
Las respuestas de foreach in bruno conde y Jon Skeet pueden convertirse en:
Console.WriteLine( "User:/tHobbies");
foreach ( var group in groupedUsers )
Console.WriteLine( "{0}:/t{1}", group.Key, group.Select( g => g.Hobby ).AsJoined( ", " ) );
... y obtendrá el formato de salida de resultados preciso que solicitó (sí, sé que los demás ya han resuelto su problema, pero es difícil de resistir)
todas las respuestas no son lo suficientemente buenas;
porque esta es una consulta de db, pero todos lo hacemos solo en la memoria;
La diferencia es que, si se produce alguna operación en la memoria, se producirá un error que no se puede trans para almacenar la expresión;
var list = db.Users.GroupBy(s=>s.User).
select(g=>new{user=g.Key,hobbys=g.select(s=>s.Hobby)}); // you can just do that from db
var result=list.ToList(); // this is important,to query data to memory;
var result2 = result.select(g=>new{user=g.Key,hobbyes=string.join(",",g.hobbyes)}; //then,do what you love in memory