Arquivos do Blog
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();
}
}
}
LINQ To XML – Como Criar e Acessar XML com LINQ
Nesse exemplo vou mostrar como podemos acessar e criar XML usando o LINQ to XML
Criando o elemento XML:
XElement Clientes = new XElement("Clientes",
new XElement("Cliente",
new XElement("ID", "1"),
new XElement("Nome", "Cliente1"),
new XElement("Endereco", "Rio de Janeiro")
),
new XElement("Cliente",
new XElement("ID", "2"),
new XElement("Nome", "Cliente2"),
new XElement("Endereco", "São Paulo")
),
new XElement("Cliente",
new XElement("ID", "3"),
new XElement("Nome", "Cliente3"),
new XElement("Endereco", "Santos")
)
);
Resultado:
<Clientes>
<Cliente>
<ID>1</ID>
<Nome>Cliente1</Nome>
<Endereco>Rio de Janeiro</Endereco>
</Cliente>
<Cliente>
<ID>2</ID>
<Nome>Cliente2</Nome>
<Endereco>São Paulo</Endereco>
</Cliente>
<Cliente>
<ID>3</ID>
<Nome>Cliente3</Nome>
<Endereco>Rio de Janeiro</Endereco>
</Cliente>
</Clientes>
Vamos agora utilizar LINQ com a classe XDocument para selecionar todos os clientes residentes no Rio de Janeiro:
XDocument doc = XDocument.Parse(Clientes.ToString());
var ClientesRJ = from p in doc.Root.Elements("Cliente")
where p.Element("Endereco").Value == "Rio de Janeiro"
select p;
foreach (var cliente in ClientesRJ)
Console.WriteLine("{0} {1}", cliente.Element("Nome").Value, cliente.Element("Endereco").Value);
Resultado:
Cliente1 — Rio de Janeiro
Cliente3 — Rio de Janeiro

