TransWikia.com

Implementar método async que devuelva un valor decimal

Stack Overflow en español Asked by Pedro Ávila on August 27, 2021

Trabajo con EFcore 3.1, Visual Studio 2019

Tengo la necesidad de implementar el siguiente método async que devuelva un valor dedimal

public async Task<decimal> SumIngreso(int operacion)
    {
        using (var context = new CatalogoInquilinoContext())
        {
            var result = from mc in context.MovimientoCajas
                         join o in context.Operaciones on mc.OperacionId equals o.OperacionId
                         where o.OperacionStatus == OperacionCaja.Abrir && o.OperacionId == operacion
                         select mc.Ingreso;

            return await !result.AnyAsync() ? 0 : result.Sum();
        }
    }

Me da el siguiente error: El operador ! no se puede aplicar el operando del tipo IQueryable<decimal>

Saludos!

2 Answers

Datos importantes cuando se hace uso del Any o AnyAsync:

  1. Devuelve True o False dependiendo si hay elementos o si la condición dada se cumple con al menos 1 elemento.
  2. Cuando utilizan Any o AnyAsync, es innecesario preguntar luego por un Count o si es diferente de null, por el motivo definido en el punto anterior. Este es un error muy común, a leer la documentación.

Código:

public async Task<decimal> SumIngreso(int operacion)
    {
        using (var context = new CatalogoInquilinoContext())
        {
            var result = from mc in context.MovimientoCajas
                         join o in context.Operaciones on mc.OperacionId equals o.OperacionId
                         where o.OperacionStatus == OperacionCaja.Abrir && o.OperacionId == operacion
                         select mc.Ingreso;

            //return await !result.AnyAsync() ? 0 : result.Sum();
            //Esto te dará True o False dependiendo si existen items dentro de result. 
            var miResultado = await result.AnyAsync();
            return miResultado ? result.Sum() : 0;
        }
    }

Lectura recomendada:

  1. https://docs.microsoft.com/es-es/dotnet/api/system.linq.enumerable.any?view=netcore-3.1

  2. https://docs.microsoft.com/en-us/dotnet/api/system.data.entity.queryableextensions.anyasync?view=entity-framework-6.2.0

Y si lo que queremos es obtener la suma de manera más directa:

public async Task<decimal> SumIngreso(int operacion)
    {
        using (var context = new CatalogoInquilinoContext())
        {
            var result = await (from mc in context.MovimientoCajas
                         join o in context.Operaciones on mc.OperacionId equals o.OperacionId
                         where o.OperacionStatus == OperacionCaja.Abrir && o.OperacionId == operacion
                         select mc.Ingreso).SumAsync();

            return result;
        }
    }

Correct answer by fredyfx on August 27, 2021

IQueryable Define una secuencia de elementos de tipo , en tu caso decimal, en vez de un simple item. Esto también te permite ejecutar operaciones adicionales sin tener que traer la secuencia en memoria.Sin embargo, esto no es importante para el contexto de la pregunta. Tu situación es sencilla, no uses directamente el operador !.

Intenta con algo como esto:

var iResult = await result.AnyAsync();
if(iResult != null || iResult.Count()>0)
{

}

Parte de la información en la que me basé es de stack en inglés traduje una parte pero la adapte al contexto de la pregunta. Se usó adicionalmente https://dotnetfiddle.net/ como compilador online.

Answered by Fabio Andrés on August 27, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP