Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

ZecaLoteiro

[Resolvido] LINQ Distinct - IEquatable - Não funcionando

Recommended Posts

Boa tarde,

 

Estou tentando usar o DISTINCT em uma consulta LINQ porém não está funcionando.

Implementei tanto a interface IEquatable quando a interface IEqualityComparer mas mesmo assim não é possível distinguir as instâncias.

 

Alguém já passou por isso? Poderia ajudar?

Desde já obrigado.

 

Public Class Teste
  Implements IEquatable(Of Teste), IEqualityComparer(Of Teste)
  Private _Codigo As Integer
  Public Property Codigo() As Integer
    Get
      Return _Codigo
    End Get
    Set(ByVal value As Integer)
      _Codigo = value
    End Set
  End Property
  Public Sub New(id As Integer)
    Me.Codigo = id
  End Sub
  
  Public Overrides Function Equals(obj As Object) As Boolean
    Return DirectCast(obj, Teste).Codigo = Me.Codigo
  End Function

  Public Function Equals1(other As Teste) As Boolean Implements IEquatable(Of Teste).Equals
    Return Me.Codigo = other.Codigo
  End Function

  Public Function Equals2(x As Teste, y As Teste) As Boolean Implements IEqualityComparer(Of Teste).Equals
    Return x.Codigo = y.Codigo
  End Function

  Public Function GetHashCode1(obj As Teste) As Integer Implements IEqualityComparer(Of Teste).GetHashCode
    Return DirectCast(obj, Teste).Codigo
  End Function
End Class

Testando:

 

Dim p1 As New Teste(78)
Dim p2 As New Teste(78)
Dim l As New List(Of Teste) From {p1, p2}
MsgBox(l.Distinct().Count())
MsgBox(l.Distinct().ToList().Count)

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Na vdd eu precisei criar uma classe separada implementando a interface IEqualityComparer e passá-la como parâmetro no método distinct:

 

Public Class TesteEqualityComparer 
    Implements IEqualityComparer(Of Teste)

    Public Function Equals2(x As Teste, y As Teste) As Boolean Implements IEqualityComparer(Of Teste).Equals
        Return x.Codigo = y.Codigo
    End Function

    Public Function GetHashCode1(obj As Teste) As Integer Implements IEqualityComparer(Of Teste).GetHashCode
        Return obj.Codigo.GetHashCode()
    End Function
End Class


MsgBox(l.Distinct(New TesteEqualityComparer()).Count())

 

 

Resolvido, obrigado pela força.

Compartilhar este post


Link para o post
Compartilhar em outros sites

  • Conteúdo Similar

    • Por mr22robot
      Ola caros amigos. 
      Estou com uma dúvida aqui que embora nao tenho achado ainda uma resposta, acredito que haja.
      Estou estudando a tão sonhada linguagem de programação asp.net core mvc. Linguagem essa que demorei 5 anos pra iniciar os estudos rsrs.
      Mas estou agarrado em uma situação. 
      Estou usando como base de dados nos meus estudos um banco Oracle. Que já tem algumas informações nele. Utilizei o SCAFFOLD para criar as classes e o contexto baseado no banco e tabelas existentes. 
      Porem agora na fase das consultas, estou perdido em como utilizar o IN que eu utilizo no oracle; no LINQ.
      Ex: 
      SELECT CODPROD,DESCRICAO FROM PRODUTO WHERE CODPROD IN(1,2,3,4,5,6) Como eu utilizo esse filtro com uma restrição de códigos de produtos? no caso o where codprod in(1,2,3,4,5,6) ?.
      Desde já obrigado pela ajuda.
    • Por dudepaiva
      Boa tarde!
      Estou buscando os dados em uma planilha e adicionando em uma lista. Antes de adicionar em uma lista, utilizo o GROUPBY para agrupar a informação desejada, até aqui tudo bem, porém quando tento lançar essa informação num COMBOBOX, ocorre erro de parametro.
      A primeira linha em negrito, é onde busco e agrupo as informações. A segunda é onde ocorre o erro.
       
      Segue código:
       
      Quero trazer os dois campos abaixo.
       
      public class ProdutoDTO
          {
              private string codigo;
              private string nomeTributario;
              private string linhaReduzida;
              private string linha;
              private string marcaReduzida;
              private string marca;
              private string gramatura;
              public ProdutoDTO()
              {
              }
              public ProdutoDTO(string codigo, string nomeTributario, string linhaReduzida, string linha, string marcaReduzida, string marca, string gramatura)
              {
                  this.Codigo = codigo;
                  this.nomeTributario = nomeTributario;
                  this.linhaReduzida = linhaReduzida;
                  this.linha = linha;
                  this.marcaReduzida = marcaReduzida;
                  this.marca = marca;
                  this.gramatura = gramatura;
              }
              public string Codigo { get => codigo; set => codigo = value; }
              public string NomeTributario { get => nomeTributario; set => nomeTributario = value; }
              public string LinhaReduzida { get => linhaReduzida; set => linhaReduzida = value; }
              public string Linha { get => linha; set => linha = value; }
              public string MarcaReduzida { get => marcaReduzida; set => marcaReduzida = value; }
              public string Marca { get => marca; set => marca = value; }
              public string Gramatura { get => gramatura; set => gramatura = value; }
          }
       
      A primeira linha em negrito, é onde busco e agrupo as informações. A segunda é onde ocorre o erro.
       
      private void AbrirArquivoExcel()
              {
                  //Configura OpenFileDialog.
                  OpenFileDialog openFD = new OpenFileDialog();
                  openFD.Title = "Localizar arquivo";
                  openFD.InitialDirectory = @"C:\Documentos\Planilhas";
                  openFD.Filter = "Arquivo Excel (*.xlsx) | *.xlsx";
                  openFD.CheckFileExists = true;
                  openFD.CheckPathExists = true;
                  openFD.ShowReadOnly = true;
                  openFD.RestoreDirectory = true;
                  openFD.ReadOnlyChecked = true;
                  if (openFD.ShowDialog() == DialogResult.OK)
                  {
                      try
                      {
                          txtOpenFD.Text = openFD.FileName;
                          var produtos = produtoBLL.Buscar(openFD.FileName, "Dados").GroupBy(x => x.Linha).ToList();
                          cbLinha.DataSource = produtos;
                          cbLinha.ValueMember = "Codigo";
                          cbLinha.DisplayMember = "Linha";
                          cbLinha.SelectedIndex = -1;
                          cbLinha.Text = "Selecione";
                          //CarregarComboBox(cbLinha, produtos, "Linha", "LinhaReduzida");
                      }
                      catch (Exception)
                      {
                          throw;
                      }
                  }
              }
       
      Desde já agradeço a ajuda! Já quebrei a cabeça!

    • Por ramonjba
      Bom dia! Pessoal, estou muito precisando da ajuda dos Srs. Tenho uma tabela, onde a cada minuto, meu script insere dados referente a consulta SNMP de determinado equipamento. Tenho uma pagina, onde os dados que a consulta coletou diferente do dado atual, é mostrado na tabela. O que acontece é o seguinte, estou utilizando o GROUP BY para selecionar apenas os dados diferentes da coluna 'canalEquipamento', mas, o problema é que, se eu estiver com o Canal registrado na tabela em 5540, realizar a alteração para o 5500, e depois voltar para o 5540, minha consulta não retorna o dado duplicado. Não posso simplesmente mostrar todas as consultas na tabela, pois como eu disse, a inserção de dados na tabela é realizada a cada minuto, dessa forma, iria ter vários dados repetidos e uma consulta enorme. Então, o que eu preciso fazer, é que: a consulta retorne os dados , que o último não seja repetido, por exemplo: Tenho do registro 1 até 50, a coluna Canal está registrada em 5500, no registro 51 até o 500, o canal mudou para 5540, e do 501 até o 700, o canal voltou para o 5500. O que eu precisaria que a consulta retornasse, seria por exemplo:

      Consulta 1 - Canal 5500
      Consulta 51 - Canal 5540
      Consulta 501 - Canal 5500
       
      Segue a imagem do exemplo do problema atual, de como a query está retornando no momento (ela está listando apenas o primeiro registro do canal, se repetir o canal, ele não aparece mais).
      QUERY: SELECT ip_equipamento, canalEquipamento, lastSNMP FROM equipamentoSNMP WHERE idEquipamento='317' GROUP BY canalEquipamento ORDER BY idConsulta DESC
       

    • Por tamabenetti
      AJUDAAAA
      Pessoal eu preciso da quantidade total de itens diferentes vendidos por cliente para cada vendedor.
       
      Eu tenho o seguinte:
      Vendedor |                     CLIENTE                                  |  PRODUTO                                 |  data_VENDA
      JOAO          |                    MERCADO  SORRISO            |                   PRESUNTO              |  01/07/2019
      JOAO          |                   PADARIA SONHO                     |                    PRESUNTO             | 03/07/2019
      JOAO          |                    SUPERCENTER                       |                      PRESUNTO             | 05/07/2019
      JOAO          |                    SUPERCENTER                       |                      PRESUNTO             |  10/07/2019
      LUIZ          |                    CONFEITARIA A                         |                     AÇUCAR                   |  15/07/2019
       
      PRECISO DESSE RESULTADO:
      Vendedor | Total clientes vendidos | total produtos diferentes vendidos POR CLIENTE
      JOAO          |                  3                        |                    3 *
      LUIZ             |                 1                       |                      1
       
      *O total é 3 porque eu preciso considerar a venda do produto por cliente, e não somente por vendedor.
       
      Quando eu utilizo o group by ele considera apenas o total de produtos vendidos por VENDEDOR, 
      e não considera a venda para clientes diferentes.
      SELECT distinct vendedor, count(distinct cliente), count(distinct produto) 
      FROM FATO_VENDAS a
      GROUP BY vendedor
       
      Por favor me ajudem!!!
    • Por Jonatas Provido
      Pessoal estou mexendo em um relatório porem quando ele me retorna ele me traz ainda em duplicidade.
      veja na imagem 
      se aguem puder me dar uma luz. 
       
      SELECT DISTINCT ITE.CODPROD,
             ITE.SEQUENCIA,
             PRO.DESCRPROD,
             ITE.AD_COMPLEMENTO,
             PAP.CODPROPARC,
             ITE.CONTROLE,
             ITE.USOPROD,
              (CASE
                WHEN VOA.CODPROD IS NULL THEN ITE.QTDNEG
                WHEN VOA.DIVIDEMULTIPLICA = 'D' THEN ITE.QTDNEG * VOA.QUANTIDADE
                ELSE ITE.QTDNEG / VOA.QUANTIDADE
              END) AS QTDNEG,
              (CASE
                WHEN VOA.CODPROD IS NULL THEN ITE.VLRUNIT
                WHEN VOA.DIVIDEMULTIPLICA = 'D' THEN ITE.VLRUNIT / VOA.QUANTIDADE
                ELSE ITE.VLRUNIT * VOA.QUANTIDADE
              END) AS VLRUNIT,
            ITE.CODVOL,
            ITE.VLRDESC,
            ITE.QTDNEG * ITE.VLRUNIT AS TOTALITEM,
            ITE.VLRTOT - ITE.VLRDESC AS TOTLIQ,
            (CASE WHEN ITE.DTINICIO IS NULL THEN
            CAB.DTPREVENT ELSE ITE.DTINICIO END) AS DTPREV,
            USU.NOMEUSU,
            ITE.VLRIPI,
            (ITE.VLRIPI / (ITE.VLRTOT - ITE.VLRDESC)) * 100 AS PERCIPI
      FROM TGFITE ITE
           INNER JOIN TGFCAB CAB ON (CAB.NUNOTA = ITE.NUNOTA)
           INNER JOIN TGFPRO PRO ON(ITE.CODPROD = PRO.CODPROD)
           LEFT JOIN TSIUSU USU ON (USU.CODUSU = ITE.AD_CODUSU)
           LEFT JOIN TGFPAP PAP
           ON ITE.CODPROD = PAP.CODPROD
           AND CAB.CODPARC = PAP.CODPARC
           AND ITE.CODVOL = PAP.UNIDADEPARC
           LEFT JOIN TGFVOA VOA ON(
           VOA.CODPROD = ITE.CODPROD AND
           VOA.CODVOL = ITE.CODVOL AND
             ((ITE.CONTROLE IS NULL AND VOA.CONTROLE = ' ')
             OR (ITE.CONTROLE IS NOT NULL AND ITE.CONTROLE = VOA.CONTROLE))
                             )
            WHERE  CAB.NUNOTA = 55854 AND  ITE.SEQUENCIA > 0
      ORDER BY ITE.SEQUENCIA

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.