none
LINQ Sub Query RRS feed

  • 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 r

    Onde 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!

    sábado, 1 de dezembro de 2012 19:43

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
    domingo, 2 de dezembro de 2012 00:27

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
    domingo, 2 de dezembro de 2012 00:27
  • 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/

    domingo, 2 de dezembro de 2012 21:40
  • 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!

    domingo, 2 de dezembro de 2012 22:03
  • Jothaz,

    Left join é bem simples, veja estes exemplos do site da msdn:

    http://msdn.microsoft.com/en-us/library/bb397895.aspx

    Vitor Mendes | Seu feedback é muito importante para todos!
    Visite o meu site: http://www.vitormendes.com.br/

    segunda-feira, 3 de dezembro de 2012 00:03
  • 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!

    segunda-feira, 3 de dezembro de 2012 18:46