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

Objetos anônimos

Boa noite, Estou criando um sistema WEB e assistindo essas magnificas aulas de Linq decidi utilizar em meu projeto, com o intuito de aprofundar mais meus conhecimentos. Porem a um pouco mais de um dia me deparei com a seguinte situação! No meu projeto estou utilizando o padrão MVC, onde possuo as seguintes pastas: DAO, Controllers e Views. O que acontece estou tentando gerar um objeto anônimo no DAO e passar o objeto para o Controllers e então através do ViewBag enviar para minha View. Mas o Objeto está chegando na View no seguinte formato:

{ valor1 = Control.Entidades.Chamado, valor2 = Control.Entidades.Usuario }

Meu problema é, como faço para trabalhar com esse retorno? Já tentei vários tipos de acessos e não obtiver sucesso :(

abaixo segue a consulta:

var query = from c in contex.Chamados
                        join u in contex.Usuarios
                        on c.UsuarioId equals u.Id
                        where c.Id == id
                        select new { valor1 = c, valor2 = u };
3 respostas

Olá, Rafael!

Em primeiro lugar, obrigado por prestigiar nosso curso de LINQ!

Em segundo lugar, o fato de você estar obtendo "Control.Entidades.Chamado" e "Control.Entidades.Usuario" no lugar de valor1 e valor2 significa que esses valores chegaram à sua View através da conversão do objeto em string, em algum lugar do seu código. Mas não se preocupe com isso, vamos nos focar na sua query.

E quanto ao seu código, pelo visto está usando Entity Framework. No curso, vimos que é desejável, sempre que possível, utilizar propriedades de navegação no lugar do join quando trabalhamos com LINQ e Entity Framework. Então podemos reescrever o seu código sem o join:

var query = from c in contex.Chamados
            where c.Id == id
            select c;

Agora você pode se perguntar: "Mas e quanto ao usuário? Minha query precisa da informação que está na tabela de usuários".

Bom, nesse caso, podemos acessar os atributos de usuário que estão na propriedade de navegação Usuario, que por sua vez está na entidade Chamado, e assim montar um novo objeto anônimo com as propriedades que interessam. Vamos supor que você precise somente do id do chamado, e o id e nome do usuário:

var query = from c in contex.Chamados
            where c.Id == id
            select new 
            { 
               ChamadoId = c.Id,
               UsuarioId = c.Usuario.Id,
               UsuarioNome = c.Usuario.Nome 
            };

Perceba como o Id e o Nome do usuário são obtidos através da propriedade de navegação Usuario. Com isso, reduzimos a necessidade de join e deixamos o código mais claro.

E outra diferença é que, em vez de um objeto anônimo contendo objetos, agora você tem um objeto anônimo contendo tipos primitivos do C#, que deixam bem claro quais são as propriedades disponíveis para usar na sua View.

Ficou mais claro agora?

Boa sorte e boas aulas!

Obrigado pelo ágil retorno Marcelo. Realizei alguns teste utilizando a propriedade de navegação e obtive o resulta a seguir: { ChamadoId = 9, UsuarioId = 1, UsuarioNome = suporte.bra } , porem, ainda não consigo acessar as propriedades através do @item.ChamadoId, gera o seguinte erro.

Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: ''object' não contém uma definição para 'ChamadoId''.

Não sei se estou fazendo do jeito errôneo por ser iniciante em asp.net.

Se alguém conseguir dar um helper ficarei muito grato :)

solução!

Rafael, nesse caso você pode utilizar uma classe concreta, em vez de um objeto anônimo:

public class ChamadoDTO
{
   public int ChamadoId { get; set; }
   public int UsuarioId { get; set; }
   public string UsuarioNome { get; set; }
}

Aí é só mudar o tipo de retorno da cláusula select:

var query = from c in contex.Chamados
            where c.Id == id
            select new ChamadoDTO
            { 
               ChamadoId = c.Id,
               UsuarioId = c.Usuario.Id,
               UsuarioNome = c.Usuario.Nome 
            };