Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

Buscando nome da categoria, sem usar include()?

Duvida, qdo eu filtro produto.Categoria.nome no linq, não da erro de NullReferenceException, porém, qdo eu uso para exibição, o erro ocorre, necessitando incluir o "Include()" para acessar as navigationProperty.

var busca = from p in contexto.Produtos
                        where p.Categoria.Nome == "Vestuário"
 //Aqui funciona o filtro normal 'p.Categoria.Nome'
            select p;

            IList<Produto> resultado = busca.ToList();

            foreach (var produto in resultado)
                Console.WriteLine(produto.Nome + produto.Preco);

            Console.ReadKey();

Porém no exemplo abaixo, é necessário colocar o 'Include((prod => prod.Categoria))'

var busca = from p in contexto.Produtos
                        where p.Categoria.Nome == "Vestuário"
 //Aqui funciona o filtro normal 'p.Categoria.Nome'
            select p;

            IList<Produto> resultado = busca.ToList();

            foreach (var produto in resultado)
                Console.WriteLine(produto.Nome + produto.Preco + 'p.Categoria.Nome');
//Neste trecho, da erro de NullReference, logo é necessário colocar o Include()

            Console.ReadKey();

Porque?

Obrigado

2 respostas
solução!

Olá, Vinicius!

Vamos ver as duas partes do código:

Usando Filtro na Query (server side)

var busca = from p in contexto.Produtos
                        where p.Categoria.Nome == "Vestuário"
 //Aqui funciona o filtro normal 'p.Categoria.Nome'
            select p;

Com o filtro na query, o que acontece é que a expressão p.Categoria.Nome utiliza a propriedade de navegação Categoria para fazer um join implícito entre a entidade Produtos e a entidade Categorias. É importante notar que essa consulta é feita no servidor SQL Server, ou seja, é traduzida para uma consulta Transact-SQL que roda diretamente no servidor e, portanto, o filtro com a expressão p.Categoria.Nome não necessita do Include().

Usando Filtro no Laço Foreach (client side)

foreach (var produto in resultado)
                Console.WriteLine(produto.Nome + produto.Preco + 'p.Categoria.Nome');
//Neste trecho, da erro de NullReference, logo é necessário colocar o Include()

A diferença entre esse código e o anterior é que agora estamos rodando um filtro no lado do cliente. O erro acontece porque quando o código c# dentro do laço foreach acessa o objeto produto, este é carregado para a memória, por padrão, somente com os atributos (colunas) da entidade (tabela) Produtos.

Se você não especificiou na query que o seu produto deve vir com a categoria incluída, você perdeu a chance de acessá-la através do produto. Por isso, quando você tenta acessar a propriedade de navegação Categoria, você encontra uma referência de objeto nula. O método Include() serve justamente para que o objeto Produto tenha a categoria "incluída" nele quando o objeto é carregado do servidor para a memória.

Um abraço

Espetacular Marcelo, muito obrigado! entendi perfeitamente =)