Construir reportes robustos en C# inicia con decisiones simples que evitan errores futuros. Aquí verás cómo retornar colecciones de forma segura, aplicar consultas con LINQ y preparar un diccionario de evaluaciones por asignatura. Todo con un enfoque práctico en Visual Studio Code y validado con depuración.
¿Cómo se construye el primer reporte de evaluaciones?
La base es obtener la lista completa de evaluaciones y manejar correctamente los casos sin datos. En lugar de devolver nulo, se retorna una lista vacía: más seguro y predecible.
Retornar lista vacía: evita comprobaciones nulas repetitivas y excepciones.
Nombre semántico: evalList como identificador claro para la lista obtenida.
Depuración en Visual Studio Code: se verifican objetos y su estado con el depurador, aunque tarda más que imprimir en consola.
Ejemplo ilustrativo:
// Respuesta segura cuando no hay evaluacionesreturnnewList<Evaluacion>();
¿Por qué retornar lista vacía y no nulo?
Simplifica el consumo de la API interna: no hay if innecesarios.
Contrato consistente: siempre llega una colección válida.
¿Cómo validar con depuración en Visual Studio Code?
Ejecutar y revisar la variable evalList con el depurador.
Confirmar que los elementos sean evaluaciones y que la cantidad coincida con lo esperado.
¿Qué habilidades se refuerzan aquí?
Buenas prácticas de retorno en C#.
Uso del depurador para inspección profunda de objetos.
¿Qué hace el segundo reporte con LINQ y distinct?
El objetivo es obtener las asignaturas que han sido evaluadas, evitando duplicados. Se parte de la lista de evaluaciones y se proyecta a asignaturas usando LINQ.
Origen de datos: la lista de evaluaciones previamente obtenida.
Proyección: seleccionar la asignatura de cada evaluación con select.
Eliminación de duplicados: aplicar distinct para quedarnos con asignaturas únicas.
Consulta ilustrativa:
// Origen: listaEvaluacionesvar asignaturas =from ev in listaEvaluaciones
select ev.Asignatura;// Evitar repetidosvar asignaturasUnicas = asignaturas.Distinct();
¿Cómo se define el origen de datos con from y select?
from ev in listaEvaluaciones: establece el conjunto a consultar.
select ev.Asignatura: proyecta solo la asignatura de cada evaluación.
¿Cómo filtrar con where y por qué es útil?
Puedes filtrar, por ejemplo, evaluaciones aprobadas con nota mayor o igual a 3.0:
var asignaturasAprobadas =from ev in listaEvaluaciones
whereev.Nota >=3.0Fselect ev.Asignatura;
Útil para reportes específicos como “asignaturas con evaluaciones aprobadas”.
¿Cómo evitar duplicados con distinct, hash code y comparer?
distinct elimina elementos repetidos, pero depende de cómo se comparan objetos.
Con objetos complejos, la comparación usa su hash code por defecto.
Si se requiere comparar por nombre, se puede proyectar a string o implementar un comparer personalizado.
Proyección a nombres para simplificar:
var nombresAsignaturasUnicas =(from ev in listaEvaluaciones
select ev.Asignatura.Nombre).Distinct();
Habilidades y keywords trabajadas:
LINQ (from, select, where, distinct).
Proyección a string y control de duplicados.
Conceptos de hash code, comparer y comparison.
¿Cómo preparar el diccionario de evaluaciones por asignatura?
El siguiente paso es un reporte más elaborado: mapear asignaturas a sus evaluaciones. La estructura natural es un diccionario donde la clave es la asignatura y el valor es una colección de evaluaciones.
Interfaz de retorno: colección por asignatura como IEnumerable<Evaluacion>.
Estructura: diccionario para agrupación clara y acceso eficiente.
Nombre claro: get diccionario de evaluaciones por asignatura.
Esqueleto ilustrativo:
// Diccionario: asignatura -> evaluacionesvar diccionarioRespuesta =newDictionary<string, IEnumerable<Evaluacion>>();// ... construcción del diccionario ...return diccionarioRespuesta;
¿Qué estructura devolver: lista o diccionario?
Lista: sirve para enumerar todo sin agrupación.
Diccionario: ideal para consultar por asignatura y construir reportes por clave.
¿Cómo nombrar métodos y variables para claridad?
get lista de evaluaciones: retorno base para todos los reportes.
get lista de asignaturas: derivado con LINQ y distinct.
get diccionario de evaluaciones por asignatura: agrupación por clave.
¿Qué flujo recomienda el reporteador?
Reusar la lista de evaluaciones ya funcional.
Derivar asignaturas únicas con distinct.
Construir el diccionario para consultas por asignatura.
¿Te gustaría ver una versión con agrupación y llenado del diccionario paso a paso? Comparte en los comentarios qué parte quieres profundizar.
IF Ternario, para devolver como resultado un listado de asignaturas o null en base al booleano que devuelve TryGetValue
Genial. Yo estaba confundido, pense que las expresiones lambda era cuando solo usabas sentencias. En lo particular me gusta más esta manera, porque lo leo como si fueran "subqueries", es decir, al resultado de llamar a esta función, ahora aplicale esta otra.
A esta altura de clase ya ni copio el código, solo atiendo
Igual, ya no me gusta este ejemplo de la escuela.
si, jajaj
Cual es la diferencia de Linq entre hacer lo siguiente? :
List.Where(condition)
from List where condition
Nínguna, en realidad el compilador lo traduce a lo mismo. Usa la que te sea más fácil.
Minuto 1:20 también podemos hacer esa condicional más corta:
// manera segura de buscar un datoreturn(_diccionario.TryGetValue(ValuesOfKeyDiccionario.Evaluacion, out IEnumerable<EscuelaBase> lista))// retornando una lista con todas las evalauciones? lista.ToList().Cast<Evaluacion>()// otherwise: retornando una lista vacia:newList<Evaluacion>();
Linq o Language Integrated Query, tiene una sintaxis similar a SQL, pero con la ventaja de que podemos escribirlo directo en nuestro código C# sobre alguna colección. En este caso para recorrer la lista de evaluaciones y que nos retorne las asignaturas debemos escribir:
from ev in listaEvaluaciones select ev.Asignatura
Codigo no fuenciona en VS Enterprise
El IEnumerable<Evaluaciones> se cambia por IEnumerable<Escuela>
Indagando un poco por la red, intente implementar el comparer con la interfaz IEqualityComparer, la cual permite hacer un distinct de una propiedad en específico de la entidad. En el siguiente url podrán encontrar como definir la Clase PropertyComparer con datos genéricos, y con el nombre de la propiedad como parámetro en el constructor.
Les muestro como es que quedó mi código para obtener la lista de asignaturas:
publicIEnumerable<Asignatura>obtenerListaAsignaturas(){var listEvaluaciones =obtenerListaEvaluaciones();return(from ev in listEvaluaciones
select ev.Asignatura).Distinct(newPropertyComparer<Asignatura>("Nombre"));}
De esta forma es posible obtener las listas de las asignaturas como objeto Asignatura como se muestra en la siguiente imagen:
El problema con ese código es que nos va a regresar todas las asignaturas contenidas en la lista de evaluaciones, aunque se encuentren repetidas. Para solucionar esto simplemente hacemos uso de la función Distinct de Linq, la cual va a eliminar los elementos duplicados.
Ejemplo de codigo para el proceso
<publicvoidcheckList(){List<Estudiantes> datos =newList<Estudiantes>();Estudiantes estudiantes =newEstudiantes(); estudiantes.nombre="Miguel"; estudiantes.apellido="Gonzalez"; datos.Add(estudiantes); estudiantes =newEstudiantes(); estudiantes.nombre="Sofia"; estudiantes.apellido="Vergara"; datos.Add(estudiantes);IEnumerable<Estudiantes> studentQuery =from student in datos
where student.apellido[0]>90 select student;}>
var listaEvaluaciones =GetListaEvaluaciones();//ejemplo LinQ// 1. declarar un alias para manipular propiedades - 'evaluacion' --> from evaluacion // 2. establecer origen de datos - listaEvaluaciones --> in listaEvaluaciones// 3. indicar condiciones/filtros de la consulta --> where evaluacion.Nota>=3.0// 4. indicar propíedades que quiere incluir en el resultado --> select evaluacion.Asignatura// *distinct --> eliminar resultados repetidos//consulta asignaturas con evaluaciones aprobadasreturn(fromEvaluacion evaluacion in listaEvaluaciones
//where evaluacion.Nota>=3.0 select evaluacion.Asignatura.Nombre).Distinct();```
Linq tiene una sintaxis parecida a SQL
La respuesta a lo de Comparable
Implementar en la clase Asignatura la interfase IEqualityComparer<Asignatura>
public bool Equals(Asignatura x,Asignatura y){return x.Nombre==y.Nombre;}public int GetHashCode(Asignatura obj){return0;}
Luego ponemos el comparador dentro de Distinct
return(fromEvaluación ev in listaEvaluaciones
select ev.Asignatura).Distinct(newAsignatura());
🤯
Muy interesante Linq
Aprendiendo linq
Vamos a crear un método que nos devuelva una lista de todas las asignaturas que tenemos en el diccionario, para ello dentro del método llamaremos a GetListaEvaluaciones y haciendo uso de Linq obtendremos las distintas asignaturas que existen.
ese groupBy es medio raro.
me pasa que la lista me arroja 0 en ambas situaciones y no se el porque