SELECIONAR ALGUNS CAMPOS COM EF

ADHEL 21/03/2017 17:38:48
#472591
Boa tarde pessoal.
Seguindo meu aprendizado com entity framework, deparei com o seguinte problema.
Gostaria de selecionar apenas alguns campos da tabela para apresentação no datagridview,
O código que estou utilizando é esse abaixo,onde aparece todos os campos da tabela

     Sub listarDados()
Dim lista As IEnumerable(Of aprendiz) = From p In contexto.aprendizs.AsNoTracking Where p.nome.Contains(pr)
With dgvAprendiz
.DataSource = lista.ToList.OrderBy(Function(x) x.nome).ToList
.ClearSelection()
.Columns([Ô]nome[Ô]).Width = 300
End With
End Sub


Pesquisando pela internet vi em tutorial do Macoratti que ele coloca um Select após a instrução e os nomes dos campos desejados.
Resolvi fazer o mesmo.O código então ficou assim.


    Dim lista As IEnumerable(Of aprendiz) = From p In contexto.aprendizs.AsNoTracking Where p.nome.Contains(pr) Select p.id, p.nome, p.registro 


Quando executo aparece essa mensagem de erro abaixo
Citação:

Additional information: Não é possível converter um objeto do tipo [ô]System.Data.Entity.Infrastructure.DbQuery'1[VB$AnonymousType_0'3[System.Int32,System.String,System.String]][ô] no tipo [ô]System.Collections.Generic.IEnumerable'1[efEntities.aprendiz][ô].


Estou a horas pesquisando e não consegui resolver.
DS2T 21/03/2017 17:55:32
#472594
Resposta escolhida
Quando você faz isso:

Dim lista As IEnumerable(Of aprendiz) = From p In contexto.aprendizs.AsNoTracking Where p.nome.Contains(pr) Select p.id, p.nome, p.registro


A partir do momento que você seleciona esses 3 campos, sem instanciar um objeto, você está criando um tipo anônimo (sem um tipo definido).
Você teria que fazer algo assim:

Dim lista As IEnumerable(Of aprendiz) = From p In contexto.aprendizs.AsNoTracking Where p.nome.Contains(pr) Select New Aprendiz() With {id = p.id, nome=p.nome, registro = p.registro}


Seria isso, ou mais ou menos isso hahaha
Sempre me confundo com essa sintaxe ...
ADHEL 21/03/2017 19:19:01
#472597
DS2T obrigado pelo retorno.
Citação:

sem instanciar um objeto, você está criando um tipo anônimo (sem um tipo definido).


Que objeto seria esse ?
KERPLUNK 21/03/2017 19:39:54
#472599
Citação:

:
DS2T obrigado pelo retorno.
sem instanciar um objeto, você está criando um tipo anônimo (sem um tipo definido).
Que objeto seria esse ?


Pura questão de sintaxe, dissecando seu código:

Dim lista As IEnumerable(Of aprendiz)

Essa parte significa: Crie uma variável que herde o comportamento da Interface [Ô]IEnumerable[Ô], baseado na classe aprendiz.


From p In contexto.aprendizs.AsNoTracking

Use a variável [Ô]p[Ô] no restante desse bloco, que será uma representação de [Ô]contexto.aprendizs[Ô] e não faça um cache desse contexto.


Where p.nome.Contains(pr)

Traga apenas os registros onde a propriedade nome contenha o que estiver na variável [Ô]pr[Ô].

Então respondendo sua pergunta, o tipo anônimo que você está criando é a variável [Ô]lista[Ô], que conterá, seja o que for que seu bloco LINQ retornar. No seu caso, são os registros que estiverem em [Ô]contexto.aprendizs[Ô], de acordo com a condição Where, onde o nome deve conter o que estiver na variável [Ô]pr[Ô].

Esse é um dos motivos de eu simplesmente não entender a preferência pelo dialeto VB.NET. Muitos dizem [Ô]estou familiarizado com a sintaxe[Ô], mas a coisa muda completamente com .NET. Comandinho pra lá e comandinho pra cá, já não é mais o comum. é necessário aprender toda uma forma nova de pensar. E se é esse o caso, porque não já fazer isso com um dialeto MUITO mais simples, amigável, dinâmico e objetivo como o C#?
DS2T 22/03/2017 15:12:02
#472620
Citação:

DS2T obrigado pelo retorno.
Citação:
sem instanciar um objeto, você está criando um tipo anônimo (sem um tipo definido).

Que objeto seria esse ?




Esse objeto que você precisaria instanciar seria o Aprendiz, como eu fiz no exemplo.
Entenda que o Select vai retornar uma nova forma de dados para você.

Exemplos:

From p In contexto.aprendizs.AsNoTracking Where p.nome.Contains(pr) Select p.id, p.nome, p.registro


Isso retornaria um Enumerable genérico para um tipo anônimo com assinatura (id, nome e registro).
Esse tipo anônimo na verdade é um tipo criado pelo compilador, sem que você precise criar a classe. Ele costuma ser usado para estruturas temporárias onde criar uma classe talvez não seja necessário, pois você usará apenas uma vez no projeto.

Por exemplo:

Dim p As New With {.Nome = [Ô]Daniel[Ô], .Idade = 25}
MessageBox.Show(p.Nome)

é um tipo anônimo com as propriedades Nome (string) e Idade (int).


No seu código, você selecionou os campos, mas não disse qual o tipo de dados que ele tava se referindo. Então ele criou esse tipo anônimo.
Mas você estava esperando um tipo Aprendiz, tanto é, que sua consulta era armazenada num tipo IEnumerable(Of aprendiz).
Quando ele tentou converter o tipo anônimo para o aprendiz, deu o pau. Porque ele não implementa um IConvertible.


Por isso recomendei você instanciar o Aprendiz, e indicar apenas os campos que você julgar necessário.
Mas você também poderia continuar usando o tipo anônimo, você só precisaria ter que mudar o IEnumerable(Of aprendiz).

Deu pra entender mais ou menos?
Tô no trabalho e digitei meio rápido.

Abraços!
JABA 23/03/2017 11:42:29
#472673
Tenta assim pra ver:

Dim lista = (From p In contexto.aprendizs Where p.nome.Contains(pr) Select p.id, p.nome, p.registro).AsNoTracking
ADHEL 23/03/2017 19:28:27
#472692
Colegas desculpe a demora em responder.

Citação:

E se é esse o caso, porque não já fazer isso com um dialeto MUITO mais simples, amigável, dinâmico e objetivo como o C#?


KERPLUNK , estou pensando seriamente em aprender C#.O meu problema é que não tenho uma mente privilegiada igual à sua, o que torna mais difícil a compreensão, além de estar desgastada com o tempo.

DS2T muito obrigado pelos esclarecimentos, estou engatinhando e algumas partes do que postou ainda tenho dificuldade em assimilar.
JABA obrigado à você também.

A sintaxe ficou assim.


    Dim lista = From p In contexto.aprendizs.AsNoTracking Where p.nome.Contains(pr) Select p.id, p.nome 


Infelizmente só posso pontuar um.Então vou pontuar o DS2T.
Agradeço aos três imensamente.
Tópico encerrado , respostas não são mais permitidas