multiple datos agrupar c# linq group-by linq-to-objects

datos - select group by linq c#



Usando LINQ para agrupar una lista de objetos (6)

Tengo un objeto:

public class Customer { public int ID { get; set; } public string Name { get; set; } public int GroupID { get; set; } }

Devuelvo una lista que puede parecerse a la siguiente:

List<Customer> CustomerList = new List<Customer>(); CustomerList.Add( new Customer { ID = 1, Name = "One", GroupID = 1 } ); CustomerList.Add( new Customer { ID = 2, Name = "Two", GroupID = 1 } ); CustomerList.Add( new Customer { ID = 3, Name = "Three", GroupID = 2 } ); CustomerList.Add( new Customer { ID = 4, Name = "Four", GroupID = 1 } ); CustomerList.Add( new Customer { ID = 5, Name = "Five", GroupID = 3 } ); CustomerList.Add( new Customer { ID = 6, Name = "Six", GroupID = 3 } );

Quiero devolver una consulta de linq que se verá como

CustomerList GroupID =1 UserID = 1, UserName = "UserOne", GroupID = 1 UserID = 2, UserName = "UserTwo", GroupID = 1 UserID = 4, UserName = "UserFour", GroupID = 1 GroupID =2 UserID = 3, UserName = "UserThree", GroupID = 2 GroupID =3 UserID = 5, UserName = "UserFive", GroupID = 3 UserID = 6, UserName = "UserSix",

Lo intenté desde

Uso de Linq para agrupar una lista de objetos en una nueva lista agrupada de lista de objetos

código

var groupedCustomerList = CustomerList .GroupBy(u => u.GroupID) .Select(grp => grp.ToList()) .ToList();

Funciona pero no da la salida deseada.


¿Es esto lo que quieres?

var grouped = CustomerList.GroupBy(m => m.GroupID).Select((n) => new { GroupId = n.Key, Items = n.ToList() });


El resultado deseado se puede obtener utilizando IGrouping , que representa una colección de objetos que tienen una clave común en este caso, un GroupID

var newCustomerList = CustomerList.GroupBy(u => u.GroupID) .Select(group => new { GroupID = group.Key, Customers = group.ToList() }) .ToList();


var groupedCustomerList = CustomerList .GroupBy(u => u.GroupID, u=>{ u.Name = "User" + u.Name; return u; }, (key,g)=>g.ToList()) .ToList();

Si no desea cambiar los datos originales, debe agregar algún método (tipo de clonación y modificación) a su clase de la siguiente manera:

public class Customer { public int ID { get; set; } public string Name { get; set; } public int GroupID { get; set; } public Customer CloneWithNamePrepend(string prepend){ return new Customer(){ ID = this.ID, Name = prepend + this.Name, GroupID = this.GroupID }; } } //Then var groupedCustomerList = CustomerList .GroupBy(u => u.GroupID, u=>u.CloneWithNamePrepend("User"), (key,g)=>g.ToList()) .ToList();

Creo que es posible que desee mostrar al Customer diferente sin modificar los datos originales. Si es así, debe diseñar su clase de Customer diferente, como esto:

public class Customer { public int ID { get; set; } public string Name { get; set; } public int GroupID { get; set; } public string Prefix {get;set;} public string FullName { get { return Prefix + Name;} } } //then to display the fullname, just get the customer.FullName; //You can also try adding some override of ToString() to your class var groupedCustomerList = CustomerList .GroupBy(u => {u.Prefix="User", return u.GroupID;} , (key,g)=>g.ToList()) .ToList();


var groupedCustomerList = CustomerList .GroupBy(u => u.GroupID) .Select(g => new { GroupId = g.Key, Items = g.Select(i => new { UserID = i.ID, UserName = string.Concat("User", i.Name), GroupId = i.GroupID }).ToList() }) .ToList();


var groupedCustomerList = CustomerList.GroupBy(u => u.GroupID) .Select(grp =>new { GroupID =grp.Key, CustomerList = grp.ToList()}) .ToList();


var result = from cx in CustomerList group cx by cx.GroupID into cxGroup orderby cxGroup.Key select cxGroup; foreach (var cxGroup in result) { Console.WriteLine(String.Format("GroupID = {0}", cxGroup.Key)); foreach (var cx in cxGroup) { Console.WriteLine(String.Format("/tUserID = {0}, UserName = {1}, GroupID = {2}", new object[] { cx.ID, cx.Name, cx.GroupID })); } }