none
Ajuda para montar expressão LINQ RRS feed

  • Pergunta

  • Ola meus caros colegas desenvolvedores estou montando um programa para gerar uma espécie de extrato sendo online eu tenho o select

    pronto q faz no banco pelo sistema antigo para gerar este extrato, então estou usando o mesmo select só q preciso o transformar em uma

    expressão linq pelo modelo q eu estou utilizando aki segue o select abaixo:

      SELECT v.TurnoID
    
         ,v.ViagemID
    
         ,v.DataInicio
    
         ,v.DataFim
    
         ,v.PontoInicio
    
    	 ,v.PontoFim
    
         ,vq.ProdutoID
    
         ,p.Abreviacao
    
    
    
    	FROM Viagens v
    
    		LEFT JOIN ViagensEqvs vq 
    
    			INNER JOIN Produtos p 
    
                ON vq.ProdutoID = p.ProdutoID
    
    		ON v.TurnoID = vq.TurnoID and 
    
              v.ViagemID = vq.ViagemID
    
        WHERE V.TURNOID =914992
    
    
    
    

     

    gostaria q vcs me ajudassem a montar uma expressão link com isso no estilo

    var encerrante = from T in entidade.Turnos
                              join......

    não estou conseguindo fazer o INNER JOIN dentro do LEFT JOIN

    se alguém puder me ajudar grato desde já

     

     


    Att Edney Desenvolvedor C#, WindowsForms, Asp.Net WebForms, Asp.Net MVC
    segunda-feira, 3 de janeiro de 2011 14:01

Respostas

  • Amigo, a chave do left join no linq é o metodo DEFAULTIFEMPTY no qual você passa o objto que será criado caso o join seja vazio http://msdn.microsoft.com/en-us/library/bb355419.aspx fiz um exemplo abaixo, veja se lhe ajuda.

    protected void Page_Load(object sender, EventArgs e)
      {
        List<Viagem> viagens = new List<Viagem>();
        List<ViagensEqv> viagensEqvs = new List<ViagensEqv>();
        List<Produto> produtos = new List<Produto>();
    
        viagens.Add(new Viagem { ViagemID = 1, NomeViagem = "Viagem 1" });
        viagens.Add(new Viagem { ViagemID = 2, NomeViagem = "Viagem 2" });
        viagens.Add(new Viagem { ViagemID = 3, NomeViagem = "Viagem 3" });
        viagens.Add(new Viagem { ViagemID = 4, NomeViagem = "Viagem 4" });
    
        produtos.Add(new Produto { ProdutoID = 1, NomeProduto = "Sanduiche" });
        produtos.Add(new Produto { ProdutoID = 2, NomeProduto = "Coca" });
        produtos.Add(new Produto { ProdutoID = 3, NomeProduto = "Cafe" });
    
        viagensEqvs.Add(new ViagensEqv { ViagemID = 1, ProdutoID = 1 });
        viagensEqvs.Add(new ViagensEqv { ViagemID = 3, ProdutoID = 2 });
        viagensEqvs.Add(new ViagensEqv { ViagemID = 3, ProdutoID = 3 });
    
        var query = from v in viagens
              join vq in viagensEqvs on v.ViagemID equals vq.ViagemID
              into tempViagensVQ
              from tempViagem in tempViagensVQ.DefaultIfEmpty(new ViagensEqv())
              join p in produtos on tempViagem.ProdutoID equals p.ProdutoID
              into tempViagensVQProdutos
              from tempVqProdutos in tempViagensVQProdutos.DefaultIfEmpty(new Produto())
              select new { v.NomeViagem, tempVqProdutos.NomeProduto };
        query.ToList();
              
    
      }
      public class Viagem
      {
        public int ViagemID { get; set; }
        public string NomeViagem { get; set; }
      }
      public class ViagensEqv 
      {
        public int ViagemID { get; set; }
        public int ProdutoID { get; set; }
      }
      public class Produto 
      {
        public int ProdutoID { get; set; }
        public string NomeProduto { get; set; }
      }
    

     


    Olavo Oliveira Neto
    Se for útil marque como resposta e faça um Developer feliz :)
    segunda-feira, 3 de janeiro de 2011 16:42
    Moderador
    • Sugerido como Resposta Harley Araujo quarta-feira, 5 de janeiro de 2011 12:35
    • Marcado como Resposta Edney Batista Silva quarta-feira, 12 de janeiro de 2011 15:01
    terça-feira, 4 de janeiro de 2011 16:06

Todas as Respostas

  • Amigo, a chave do left join no linq é o metodo DEFAULTIFEMPTY no qual você passa o objto que será criado caso o join seja vazio http://msdn.microsoft.com/en-us/library/bb355419.aspx fiz um exemplo abaixo, veja se lhe ajuda.

    protected void Page_Load(object sender, EventArgs e)
      {
        List<Viagem> viagens = new List<Viagem>();
        List<ViagensEqv> viagensEqvs = new List<ViagensEqv>();
        List<Produto> produtos = new List<Produto>();
    
        viagens.Add(new Viagem { ViagemID = 1, NomeViagem = "Viagem 1" });
        viagens.Add(new Viagem { ViagemID = 2, NomeViagem = "Viagem 2" });
        viagens.Add(new Viagem { ViagemID = 3, NomeViagem = "Viagem 3" });
        viagens.Add(new Viagem { ViagemID = 4, NomeViagem = "Viagem 4" });
    
        produtos.Add(new Produto { ProdutoID = 1, NomeProduto = "Sanduiche" });
        produtos.Add(new Produto { ProdutoID = 2, NomeProduto = "Coca" });
        produtos.Add(new Produto { ProdutoID = 3, NomeProduto = "Cafe" });
    
        viagensEqvs.Add(new ViagensEqv { ViagemID = 1, ProdutoID = 1 });
        viagensEqvs.Add(new ViagensEqv { ViagemID = 3, ProdutoID = 2 });
        viagensEqvs.Add(new ViagensEqv { ViagemID = 3, ProdutoID = 3 });
    
        var query = from v in viagens
              join vq in viagensEqvs on v.ViagemID equals vq.ViagemID
              into tempViagensVQ
              from tempViagem in tempViagensVQ.DefaultIfEmpty(new ViagensEqv())
              join p in produtos on tempViagem.ProdutoID equals p.ProdutoID
              into tempViagensVQProdutos
              from tempVqProdutos in tempViagensVQProdutos.DefaultIfEmpty(new Produto())
              select new { v.NomeViagem, tempVqProdutos.NomeProduto };
        query.ToList();
              
    
      }
      public class Viagem
      {
        public int ViagemID { get; set; }
        public string NomeViagem { get; set; }
      }
      public class ViagensEqv 
      {
        public int ViagemID { get; set; }
        public int ProdutoID { get; set; }
      }
      public class Produto 
      {
        public int ProdutoID { get; set; }
        public string NomeProduto { get; set; }
      }
    

     


    Olavo Oliveira Neto
    Se for útil marque como resposta e faça um Developer feliz :)
    segunda-feira, 3 de janeiro de 2011 16:42
    Moderador
  • Olá Olavo agradeço desde já a ajuda
    Tentei do gto q vc falou adaptando o código a minha necessidade
    só que não sei o pq ele ensiste em dar erro

    Eu estou trabalhando com DLLs uma delas fica o mapa do banco
    a outra contém toda a lógica e nela onde eu estou fazendo a consulta
    ela da erro em alguns métodos como DefaultIfEmpty() ele diz q o
    namespace do LINQ não da suporte a esse método ao fazer a consulta
    não vo conseguir lhe postar mais detalhes pq a aplicação fica no serviço
    ela até fica comigo mais o banco não
    outro detalhe bem estranho é fazer um join com multiplas clausulas
    ao tentar fazer

    from v in entidade.Viagens
    join vq in entidade.ViagensQtd
    on
    new{
        v.ViagemID, v.TurnoID
    }
    equals
    new{
        vq.ViagemId, vq.TurnoId
    }

    ela da erro no join diz q há algo incompativel sendo q os campos são do msmo tipo
    mas se eu fizer com a relação do linq assim

    from v in entidade.Viagens
    join vq in entidade.ViagensQtd
    on
    new{
        v.ViagemID, v.TurnoID
    }
    equals
    new{
        vq.Viagens.ViagemID, vq.Viagens.TurnoID
    }

    Ele "da certo" ele já não gera o erro mas parece q não busca tudo essa parte de linq ainda não domino bem
    mas se puderem ir me ajudando sou grato no q eu solucionar posto o código ake e por tudo até agora
    Agradeço mto

     

     

     


    Att Edney Desenvolvedor C#, WindowsForms, Asp.Net WebForms, Asp.Net MVC
    segunda-feira, 3 de janeiro de 2011 22:07
  • Amigo,

    estranho ele não estar localizando o DefaultIfEmpty, você esta referenciando a última versão da biblioteca System.Linq ?

    quanto ao problema dos IDs que estão dando como se fossem tipos diferentes, algum deles é do tipo Nullable Int (int?) se for você precisa colocar o nome dele .Value, por exemplo se TurnoID for do tipo int?: v.TurnoID.Value


    Olavo Oliveira Neto
    Se for útil marque como resposta e faça um Developer feliz :)
    terça-feira, 4 de janeiro de 2011 11:05
    Moderador
  • Olá Sr. Olavo primeiramente grato pelo retorno
    bom no meu projeto ele não tem a ultima versão do Linq
    pois estou trabalhando com Framework 3.5 nele porcausa das
    limitações do IIS na empresa ao publicar site está pois eles
    usam uma versão incompativel com o 4.0 eles usam o
    IIS 5.1 aki então estou me obrigando a usar o 3.5
    gostaria de saber se este método é compativel com este
    framework ou somente msmo no f 4.0 vou conseguir usalo
    se for este o caso vou migra todo o projeto para f 4.0
    e ver se consigo uma máquina aqui para rodar a aplicação

    grato desde já


    Att Edney Desenvolvedor C#, WindowsForms, Asp.Net WebForms, Asp.Net MVC
    terça-feira, 4 de janeiro de 2011 12:47
  • segundo o site da microsoft, este metodo é existente tanto na versão 3.5 como na 4.0 você so precisa referenciar no topo da classe o using System.Linq
    Olavo Oliveira Neto
    Se for útil marque como resposta e faça um Developer feliz :)
    terça-feira, 4 de janeiro de 2011 12:56
    Moderador
  • Olá Sr. Olavo bom está sim sendo referenciada esta biblioteca no inicio da aplicação:

    au tentar utilizar-me deste método ele gera a seguinte exception

    NotSupportedException:

    LINQ to Entities não reconhece o método 'System.Collections.Generic.IEnumerable`1[EoclDBLibrary.EF.Produtos] DefaultIfEmpty[Produtos](System.Collections.Generic.IEnumerable`1[EoclDBLibrary.EF.Produtos])', que não pode ser convertido em uma expressão de armazenamento.


    eu até lhe mandaria um print mas não sei como colar ake o meu linq está assim:

          var encerrante = from v in entidade.Viagens
                   join vq in entidade.ViagensEqvs on
                  new { v.TurnoID, v.ViagemID }
                    equals
                    new { vq.Viagens.TurnoID, vq.ViagemID}
                   into t
                   from vs in t
                    join p in entidade.Produtos
                    on vs.ProdutoId equals p.ProdutoID
                    into d              
                   from p in d.DefaultIfEmpty()
                   join e in entidade.Turnos
                   on v.TurnoID equals e.TurnoID
                   where v.TurnoID == TurnoID
                  select new {
                    TurnoID = e.TurnoID != null ? e.TurnoID : 0,
                    DataIni = e.DataIni != null ? e.DataIni : new DateTime(),
                    DataFim = e.DataFim != null ? e.DataFim : new DateTime(), 
                    Prefixo = e.Prefixo != null ? e.Prefixo : 0,
                    CatracaIni = e.CatracaIni != null ? e.CatracaIni : 0,
                    CatracaFim = e.CatracaFim != null ? e.CatracaFim : 0, 
                    e.MotoristaID ,
                    p.Familias.FamiliaID,
                    p.Abreviacao,
                    vs.valorUnitario,
                    quantidade = vs.creditos,
                    contador = vs.creditos
                  };
    

    ele simplesmente não reconhece o método

    mas uma vez grato por sua atenção

    fico no aguardo

    Abraços


    Att Edney Desenvolvedor C#, WindowsForms, Asp.Net WebForms, Asp.Net MVC
    terça-feira, 4 de janeiro de 2011 14:29
    • Sugerido como Resposta Harley Araujo quarta-feira, 5 de janeiro de 2011 12:35
    • Marcado como Resposta Edney Batista Silva quarta-feira, 12 de janeiro de 2011 15:01
    terça-feira, 4 de janeiro de 2011 16:06
  • Olá a todos bom trago boas e mas noticias em relação ao meu problema, antes de tudo peço disculpas por
    não ter respondido antes como o projeto fica no serviço e não trabalho só com o desenvolvimento na mesma
    o tempo fica curto. De ante mão agradeço dizendo que estão sendo muito uteis e proveitosas as dicas aki pos-
    tadas mas agora vem o porém, eu consegui fazer funcionar mas apenas com .net 4.0 no vs 2010 já no vs 2008
    .net 3.5 ainda estou  na mesma ele da este mesmo erro para de que este método não é suportado nesta versão
    no caso não há uma referencia do mesmo mas vou dar mais uma procurada sobre este erro e logo posto com
    mais novidades sobre o caso e aguardo algum retorno em relação ao mesmo

    Muito grato a atenção de todos

     

     


    Att Edney Desenvolvedor C#, WindowsForms, Asp.Net WebForms, Asp.Net MVC
    quarta-feira, 5 de janeiro de 2011 16:15