Sum com Linq e valores Nullable
Vamos imaginar a seguinte situação.
Temos uma lista de produtos com nome e valor, o valor do produto pode ser nulo:
public class Produto {
public string Nome { get; set; }
public decimal? Valor { get; set; }
}
vamos agora tentar obter o valor total dos produtos:
List lista = db.GetProdutos(); decimal soma = lista.Sum(c => c.Valor);
Ao rodar o código, se houver um produto com valor nulo, tomamos um erro.
The cast to value type ‘Decimal’ failed because the materialized value is null. Either the result type’s generic parameter or the query must use a nullable type.
Como resolver este problema?
Para resolver é bem simples, precisamos apenas usar um comando muito útil no C# e que pouca gente conhece, o Null Coalescing (??):
decimal soma = lista.Sum(c => c.Valor ?? 0);
ou com Linq:
decimal soma = (from p in lista
select p.Valor ?? 0).Sum();
No exemplo acima, com o ?? estou dizendo que é para retornar o Valor diferente de nulo ou 0, Semelhante ao If abaixo:
(p.Valor != null) : p.Valor ? 0
Segue abaixo um código completo mostrando o funcionamento da dica, basta criar um novo projeto Console Application e inserir o código abaixo:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
public class Produto
{
public string Nome { get; set; }
public decimal? Valor { get; set; }
}
class Program
{
static void Main(string[] args)
{
List<Produto> lista = new List<Produto>();
lista.Add(new Produto
{
Nome = "Teste 1",
Valor = (decimal)54.2
});
lista.Add(new Produto
{
Nome = "Teste 2",
Valor = null
});
lista.Add(new Produto
{
Nome = "Teste 3",
Valor = 65
});
decimal soma = (from p in lista
select p.Valor ?? 0).Sum();
Console.WriteLine(soma);
Console.ReadKey();
}
}
}
Publicado em 22 de janeiro de 2012, em .NET Framework, C#, LINQ e marcado como .NET Framework, C#, LINQ, Null Coalescing, Nullable, Sum. Adicione o link aos favoritos. 4 Comentários.


Perguntei isto outro dia ao meu instrutor e te digo com certeza que poucos conhecem, pois ele deu risada de mim quando perguntei deste conceito, mais eu nem bravejei nem nada pois sei o quanto é difícil se manter atualizado.
Grande abraço Pedro,
e como sempre parabens pelos posts de excelente qualidade e atualidade.
aqui não deu certo, o que poderá ser?
no VS da essa mensagem:
Error 1 Operator ‘??’ cannot be applied to operands of type ‘decimal’ and ‘int’ C:\Sites em Desenvolvimento\EF.CasaPlacas\EF.CasaPlacas.Web\SaldoCaixa.aspx.cs 37 49 EF.CasaPlacas.Web
Estranho, deveria funcionar.
Te mandei por e-mail um exemplo do código funcionando e pedi para você me mandar o código da linha que está dando erro. vou aproveitar e colocar o mesmo exemplo no post
aqui não deu certo acho que o problema pode ser que trago os valores de um edmx
placasEntities model = new placasEntities();
public decimal Saldo(int empresa)
{
DateTime data = DateTime.Now.Date;
decimal debito = (from e in model.caixa
where e.id_empresa == empresa && e.status.Equals(“A”) && e.dt_cadastro == data
&& e.tipo.Equals(“D”)
select e.valor ?? 0).Sum();
}
Esse é o erro:
Error 1 Operator ‘??’ cannot be applied to operands of type ‘decimal’ and ‘int’ C:\Sites em Desenvolvimento\EF.CasaPlacas\EF.CasaPlacas.Data\CaixaDao.cs 44 41 EF.CasaPlacas.Data