Agrupar por columna múltiple en LINQ en C #

Tenga en cuenta: He visto que hay muchas preguntas como esta en el desbordamiento de stack. Pero no funcionan para mí porque tengo una situación ligeramente diferente. Así que, por favor, no lo marque como duplicado hasta que lea la pregunta completa correctamente y entienda el escenario que quiero.

Tengo una clase como la siguiente:

public class ActualClass { public string BookName { get; set; } public string IssuerName { get; set; } public DateTime DateOfIssue { get; set; } public bool Status { get; set; } } 

Tiene los siguientes datos en la tabla: introduzca la descripción de la imagen aquí

Me gustaría agruparlos por IssuerName y DateOfIssue para la siguiente clase de viewModel:

 public class ViewModel { public string IssuerName { get; set; } public DateTime DateOfIssue { get; set; } public List Books { get; set; } } 

Y los datos se mostrarán de la siguiente manera: (Los datos de la captura de pantalla se reemplazarán por los datos de la tabla anterior después de la agrupación exitosa ) introduzca la descripción de la imagen aquí

Atención especial: ¿Hay algún problema en mi ViewModel según mis expectativas?

Intenté mucho después de seguir algunas respuestas de stackoverflow pero ninguna funcionó para mí. Cualquier ayuda será muy apreciada.

El código que he probado:

 var viewmodel = from b in db.BookIssues group b by new { b.IssuerName, b.DateOfIssue } into g select new ViewModel() { Name = g.key.IssuerName, DateOfIssue = g.Key.DateOfIssue, Books = g.ToList() //Actually this line of code is not working }; 

Books = g.ToList () // En realidad, esta línea de no funciona

Probablemente porque la propiedad de Libros es un tipo de List , no List .

Por favor, puede intentar esta consulta, agregué b.Select(bn => bn.BookName).ToList() para extraer solo los nombres de los libros:

 var books = new List { new ActualClass { BookName = "A", DateOfIssue = new DateTime(2015, 10, 10, 10, 10, 0), IssuerName = "1" }, new ActualClass { BookName = "B", DateOfIssue = new DateTime(2015, 10, 10, 10, 10, 0), IssuerName = "1" }, new ActualClass { BookName = "C", DateOfIssue = new DateTime(2015, 10, 10, 10, 10, 0), IssuerName = "1" }, new ActualClass { BookName = "D", DateOfIssue = new DateTime(2015, 10, 10, 10, 10, 0), IssuerName = "2" }, new ActualClass { BookName = "E", DateOfIssue = new DateTime(2015, 10, 10, 12, 10, 0), IssuerName = "2" }, new ActualClass { BookName = "F", DateOfIssue = new DateTime(2015, 10, 10, 12, 10, 0), IssuerName = "2" } }; var result = books.GroupBy(x => new { x.IssuerName, x.DateOfIssue }) .Select(b => new ViewModel { Books = b.Select(bn => bn.BookName).ToList(), // Accessing to DateOfIssue and IssuerName from Key. DateOfIssue = b.Key.DateOfIssue, IssuerName = b.Key.IssuerName }); 

x.IssuerName, x.DateOfIssue por: x.IssuerName, x.DateOfIssue . Hice eso al pasar un tipo anónimo en GroupBy() de la siguiente manera: x => new { x.IssuerName, x.DateOfIssue } .

Ahora están en clave y puede acceder a IssuerName y DateOfIssue desde KEY en la instrucción SELECT como en: b.Key.IssuerName y b.Key.DateOfIssue .

si necesita seleccionar la lista de libros del resultado del grupo, necesita Books = v.Select(c=>c.BookName).ToList() también tenga en cuenta que en el caso de que tenga tiempo en la fecha de emisión, es posible que deba agrupar por solo la parte de la fecha usando la función EntityFunctions.TruncateTime . Si solo almacena la fecha, puede ignorar esta función.

 var viewmodel = db.BookIssues.GroupBy(x=>new {IssuerName =x.IssuerName, DateOfIssue=EntityFunctions.TruncateTime(x.DateOfIssue) }) .Select(v=>new ViewModel(){IssuerName =v.Key.IssuerName, DateOfIssue = v.Key.DateOfIssue, Books = v.Select(c=>c.BookName).ToList() }) .ToList();