Tengo esta consulta:
int maxShoeSize = Workers
.Where(x => x.CompanyId == 8)
.Max(x => x.ShoeSize);
¿Qué habrá maxShoeSizesi la empresa 8 no tiene trabajadores?
ACTUALIZACIÓN:
¿Cómo puedo cambiar la consulta para obtener 0 y no una excepción?

maxShoeSize?' si ya lo habías probadoRespuestas:
El cero en
DefaultIfEmptyno es necesario.fuente
Max()a una secuencia vacía da como resultado un error.Sé que esta es una pregunta antigua y la respuesta aceptada funciona, pero esta pregunta respondió a mi pregunta sobre si un conjunto tan vacío daría como resultado una excepción o un
default(int)resultado.Sin embargo, la respuesta aceptada, aunque funciona, no es la solución ideal en mi humilde opinión, que no se da aquí. Por lo tanto, lo estoy proporcionando en mi propia respuesta para el beneficio de cualquiera que lo esté buscando.
El código original del OP fue:
Así es como lo escribiría para evitar excepciones y proporcionar un resultado predeterminado:
Esto hace que el tipo de retorno de la
Maxfunción seaint?, lo que permite elnullresultado y luego??reemplaza elnullresultado con0.EDITAR
Solo para aclarar algo de los comentarios, Entity Framework actualmente no admite la
aspalabra clave, por lo que la forma de escribirla cuando se trabaja con EF sería:Dado que
[TypeOfWorkers]podría ser un nombre de clase largo y es tedioso de escribir, he agregado un método de extensión para ayudar.Esto sólo mangos
int, pero el mismo se podría hacer paralong,doubleo cualquier otro tipo de valor que necesita. El uso de este método de extensión es muy simple, simplemente pasa su función de selector y opcionalmente incluye un valor que se utilizará para nulo, que por defecto es 0. Por lo tanto, lo anterior podría reescribirse así:Esperemos que eso ayude a las personas aún más.
fuente
DefaultIfEmptyrespuesta más popular solo funciona bien cuandoMaxno se está haciendo una evaluación.Selectcomo intermediario cuando solo voy a usar una función agregada comoMaxen el resultado. También pienso (no lo he probado aún) que el SQL generado usaría una consulta de subselección adicional al hacer eso, mientras que el mío solo trataría con un conjunto vacío al devolver nulo. ¡Gracias por el voto y los comentarios! ;)ShoeSizeera en realidad en una relacionadaUniformentidad, yo no usoWorkers.Where(x => x.CompanyId == 8).Select(x => x.Uniform).Max(x => x.ShoeSize), en vez me acaba de mantener toda la evaluación de laMaxfunción:Workers.Where(x => x.CompanyId == 8).Max(x => x.Uniform.ShoeSize). Prefiero utilizar la menor cantidad de métodos posible en mis consultas para permitir que EF tenga la mayor libertad para decidir cómo construir consultas de manera eficiente. ;-)public static TResult MaxOrDefault<TElement, TResult>(this IQueryable<TElement> items, Expression<Func<TElement, TResult>> selector, TResult defaultValue = default) where TResult : struct => items.Select(selector).Max(item => (TResult?)item) ?? defaultValue;Max () no devolverá nada en ese caso.
Levantará InvalidOperationException ya que la fuente no contiene elementos.
fuente
InvalidOperationExceptionsi los objetos en la lista son de tipo no anulable: docs.microsoft.com/en-us/dotnet/api/…fuente
Si esto es Linq to SQL, no me gusta usarlo
Any()porque da como resultado múltiples consultas al servidor SQL.Si
ShoeSizeno es un campo anulable, entonces usar solo el.Max(..) ?? 0no funcionará, pero lo siguiente sí:Absolutamente no cambia el SQL emitido, pero devuelve 0 si la secuencia está vacía porque cambia el
Max()para devolver un enint?lugar de unint.fuente
(suponiendo que
ShoeSizesea de tipoint)Si
Workerses unDbSetoObjectSetde Entity Framework, su consulta inicial arrojaría unInvalidOperationException, pero no se quejaría de una secuencia vacía, pero se quejaría de que el valor materializado NULL no se puede convertir en unint.fuente
Max lanzará System.InvalidOperationException "La secuencia no contiene elementos"
fuente
NB: la consulta con
DefaultIfEmpty()puede ser significativamente más lenta . En mi caso, fue una consulta simple con.DefaultIfEmpty(DateTime.Now.Date).Era demasiado vago para perfilarlo, pero obviamente EF trató de obtener todas las filas y luego tomar el
Max()valor.Conclusión: a veces el manejo
InvalidOperationExceptionpuede ser la mejor opción.fuente
Puede usar un ternario dentro
.Max()para manejar el predicado y establecer su valor;Debería manejar que la
Workerscolección sea nula / vacía si es una posibilidad, pero dependería de su implementación.fuente
Puedes probar esto:
fuente
Puede verificar si hay trabajadores antes de hacer el Max ().
fuente