Pergunta

Eu estou tentando usar o "exceto" método em um conjunto de resultados LINQ usando uma implementação personalizada se IEqualityComparer para excluir certos resultados com base no valor de um único campo do conjunto de resultados.

Assim, de forma simplificada eu tenho ...

'' Get collection of published sites...
Dim List1  = (From i In db.Sites _
              Where (i.StatusID = published) _
              Select i.SiteID, _
                     i.SiteName)

'' Find those with a pending site, but exclue all those whose SiteID is in List1...
Dim insComparer = New insCompare
Dim List2 = (From i In db.Sites _
             Where (i.StatusID = pending) _
             Select i.SiteID, _
                    i.SiteName).Except(List1, insComparer)

Meu Comparer é o seguinte ...

Public Class insCompare
    Implements System.Collections.Generic.IEqualityComparer(Of Object)

    Public Function Equals1(ByVal x As Object, ByVal y As Object) As Boolean Implements System.Collections.Generic.IEqualityComparer(Of Object).Equals
        Return IIf(x.SiteID = y.SiteID, True, False)

    End Function

    Public Function GetHashCode1(ByVal x As Object) As Integer Implements System.Collections.Generic.IEqualityComparer(Of Object).GetHashCode
        Return x.SiteID.ToString.ToLower.GetHashCode()

    End Function

End Class

Eu recebo uma exceção de elenco inválido na linha ".Except" com a mensagem "Não é possível objeto fundido do tipo '... insCompare' para digitar 'System.Collections.Generic.IEqualityComparer'"

Alguém pode lançar luz sobre por que isso pode ser por favor.

Foi útil?

Solução

O problema aqui é que você implementar IEqualityComparer (Of Object), mas as suas listas são List (Of AT), onde AT é um tipo anônimo, para que você não pode implementar IEqualityComparer (Of AT).

Eu acho que suas escolhas são:

  1. Declarar uma classe / struct para segurar o SideID / SiteName, e selecione em uma instância dessa classe, em seguida, implementar IEqualityComparer (Of NewClass).
  2. Use as chamadas de ligação tardia (ie. opção off explícita, como parece que você está fazendo agora), e colocar um .Cast (Of Object) () chamada em ambas as listas antes de chamar Exceto.

Outras dicas

Use o código a seguir.

    from t in db.Sites
where
  !
    (from t0 in db.Sites2
    select new {
      t0.SomeID
    }).Contains(new { t.SomeID })
select t

este é baseado em não em condição. Eu acho que isso vai te ajudar. U estão fazendo alguma coisa complexa.

Parece que ele está pedindo que seu comparer implementar o IEqualityComparer interface de não-genérico, enquanto teus implementos IEqualityComparer (Of Object), que é uma interface diferente.

Parece que você está usando um banco de dados como o back-end. Você não pode fornecer um comparador personalizado para isso, como ele não pode ser mapeado para TSQL.

Você já tentou Contains? ou seja where !List1.Contains(i.SiteID)?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top