Usuário com melhor resposta
LINQ Sub Query

Pergunta
-
Pessoal,
Na verdade meu problema ainda é oLEFT JOIN no framework 3.5 como pode ser visto no post:
http://social.msdn.microsoft.com/Forums/pt-BR/linqpt/thread/05c73773-b8d1-4dfa-97b6-0db2ac3f88a2
Com até o momento não consegui avançar estou verificando outras formas de contornar o problema.
Então pensei em fazer assim:
SQL:
select r.NUM_ID,
r.NUM_ID_USUARIO ,
ll = (select DES_LOGIN from TUSUARIO where TUSUARIO.num_id_usuario = r.NUM_ID_USUARIO)
from tabrec rOnde consigo trazer todos oregistro da tabela REC e o nome do usuario da bela TUSUARIO o que faz a vez do LEFT JOIN
Ai criei o Linq:
var res = (from b in DB.rec
select new
{
codigo = b.NUM_ID_REC,
usuarioConferente = b.NUM_ID_USUARIO_CONFERENTE,
nomeUsuarioConferente = (from u in DB.TUSUARIO where u.NUM_ID_USUARIO == b.NUM_ID_USUARIO_CONFERENTE select new { u.DES_LOGIN })
}).ToList();Roda porém no campo nomeUsuarioConferente vem com EnumerableQuery<> (0 items) e não consigo pegar o valor do campo DES_LOGIN.
Como escrever o meu SQL com subquer em LINQ?
Ninguém falou que seria fácil!
Respostas
-
Resolvi assim:
Então contornei o problema da seguinte forma:
from b in TRECEBIMENTO
select new
{
codigo = b.NUM_ID_RECEBIMENTO,
usuarioRealizador = b.NUM_ID_USUARIO_REALIZADOR,
usuarioConferente = b.NUM_ID_USUARIO_CONFERENTE,
nome_login = (from u in TUSUARIO where u.NUM_ID_USUARIO == b.NUM_ID_USUARIO_CONFERENTE select u.DES_LOGIN).FirstOrDefault()
}Ou
TRECEBIMENTO
.Select (
b =>
new
{
codigo = b.NUM_ID_RECEBIMENTO,
usuarioRealizador = b.NUM_ID_USUARIO_REALIZADOR,
usuarioConferente = b.NUM_ID_USUARIO_CONFERENTE,
nome_login = TUSUARIO
.Where (u => ((Int64?)(u.NUM_ID_USUARIO) == b.NUM_ID_USUARIO_CONFERENTE))
.Select (u => u.DES_LOGIN)
.FirstOrDefault ()
}
)
Não sei se é a melhor.Gostaria da opinião de alguém com mais experiência.
Ninguém falou que seria fácil!
- Marcado como Resposta jothaz quarta-feira, 5 de dezembro de 2012 18:32
Todas as Respostas
-
Resolvi assim:
Então contornei o problema da seguinte forma:
from b in TRECEBIMENTO
select new
{
codigo = b.NUM_ID_RECEBIMENTO,
usuarioRealizador = b.NUM_ID_USUARIO_REALIZADOR,
usuarioConferente = b.NUM_ID_USUARIO_CONFERENTE,
nome_login = (from u in TUSUARIO where u.NUM_ID_USUARIO == b.NUM_ID_USUARIO_CONFERENTE select u.DES_LOGIN).FirstOrDefault()
}Ou
TRECEBIMENTO
.Select (
b =>
new
{
codigo = b.NUM_ID_RECEBIMENTO,
usuarioRealizador = b.NUM_ID_USUARIO_REALIZADOR,
usuarioConferente = b.NUM_ID_USUARIO_CONFERENTE,
nome_login = TUSUARIO
.Where (u => ((Int64?)(u.NUM_ID_USUARIO) == b.NUM_ID_USUARIO_CONFERENTE))
.Select (u => u.DES_LOGIN)
.FirstOrDefault ()
}
)
Não sei se é a melhor.Gostaria da opinião de alguém com mais experiência.
Ninguém falou que seria fácil!
- Marcado como Resposta jothaz quarta-feira, 5 de dezembro de 2012 18:32
-
Jothas,
É meio difícil de julgar alguns códigos, só achei estranho no seu primeiro código usando de LINQ queries você não faz cast da sua propriedade "NUM_ID_USUARIO", mais no seu segundo código com lambda expression o cast é feito para Int64?, isto é realmente necessário ??
Tente ver o T-SQL que foi gerado pelo LINQ e comparar se era realmente isto que você esperava:
http://news.pcfviana.com/2011/12/19/como-visualizar-o-t-sql-gerado-pelo-linq-to-sql-ou-entity-framework-na-consulta-linq/Vitor Mendes | Seu feedback é muito importante para todos!
Visite o meu site: http://www.vitormendes.com.br/ -
Vitor valeu a ajuda.
Estas expressões utilizei o LinqPad e só graças a ele consegui chegar a esta expressão.
Inclusive implementei em c# e funcionou sem problemas.
Concordo que é dificil emtir um paracer sobre um código, afinal ão tantas formas de se fazer a mesma coisa.
Na verdade queria só confirma que esta é a forma de rodar uma subquery, pois na verdade o meu problema era o Lft Join n3.5 então usei da artimanha acima para contornar o problema.
Agora se alguém souber como fazer o left join certinho peço uma força.
Ninguém falou que seria fácil!
-
Jothaz,
Left join é bem simples, veja estes exemplos do site da msdn:
http://msdn.microsoft.com/en-us/library/bb397895.aspxVitor Mendes | Seu feedback é muito importante para todos!
Visite o meu site: http://www.vitormendes.com.br/ -
Vitor,
Agredeço imensamente a atenção dispensada.
Sou iniciante em LINQ ea s vezes me perco um pouco neste universo.
E talvez não tenha exposto o poroblema com o devido detalhamento.
Normalmente utilizo VS2010 com .NET 4.0 e realmente é muito simples e funciona perfeitamente utilizando DefaultIfEmpty().
Estamos efetuando manutenção em uma aplicação desenvolvida em VS2008 com .NET 3.5 (e não tem como alterar esta configuração de ambiente) onde necessito criar queries LINQ com LEFT JOIN. Então utilizei DefaultIfEmpty() porém retorna o erro:
System.NotSupportedException was unhandled by user code
Message="LINQ to Entities não reconhece o método 'System.Collections.Generic.IEnumerable`1[DBModelModel.TUSUARIO] DefaultIfEmpty[TUSUARIO](System.Collections.Generic.IEnumerable`1[DBModelModel.TUSUARIO])', que não pode ser convertido em uma expressão de armazenamento."
Então criei o post:
http://social.msdn.microsoft.com/Forums/pt-BR/linqpt/thread/05c73773-b8d1-4dfa-97b6-0db2ac3f88a2
Para tratar do assunto.
Após pesquisas confirmei que DefaultIfEmpty() não existe para o .NET 3.5:
http://social.msdn.microsoft.com/Forums/da/adodotnetentityframework/thread/5a265e03-ce8f-4804-bcbe-74d9dded0654
Como preciso de uma solução que deve utilizar o LINQ parti para a solução que esta neste post. Criei um subquey que retorna meus registro corretamente.
Então consegui uma solução para o meu problema só gostaria de confirmar com alguém mais experiente se esta solução pode ser considerada um boa prática.
Ou algém consegue uma forma de executar o DefaultIfEmpty() ou similar no .NET 3.5.
Algum corajoso se habilita?
Ninguém falou que seria fácil!