LINQ Tranne l'utilizzo del comparatore personalizzato
-
06-07-2019 - |
Domanda
Sto cercando di utilizzare il " Tranne " metodo su un set di risultati LINQ utilizzando un'implementazione personalizzata se IEqualityComparer per escludere determinati risultati in base al valore di un singolo campo dal set di risultati.
Quindi, in forma semplificata, ho ...
'' 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)
Il mio comparatore è il seguente ...
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
Ricevo un'eccezione di cast non valida su " .Except " riga con il messaggio " Impossibile eseguire il cast dell'oggetto di tipo '... insCompare' per digitare 'System.Collections.Generic.IEqualityComparer' "
Qualcuno può far luce sul perché questo potrebbe essere per favore.
Soluzione
Il tuo problema qui è che implementi IEqualityComparer (Of Object), ma i tuoi elenchi sono List (Of AT) in cui AT è un tipo anonimo, quindi non puoi implementare IEqualityComparer (Of AT).
Penso che le tue scelte siano:
- Dichiara una classe / struttura per contenere SideID / SiteName e seleziona in un'istanza di quella classe, quindi implementa IEqualityComparer (Of NewClass).
- Usa le chiamate in ritardo (cioè l'opzione esplicita disattivata, come sembra che stai facendo ora) e metti una chiamata .Cast (Of Object) () su entrambi gli elenchi prima di chiamare Except.
Altri suggerimenti
Usa il seguente codice.
from t in db.Sites
where
!
(from t0 in db.Sites2
select new {
t0.SomeID
}).Contains(new { t.SomeID })
select t
questo si basa su non in condizione. Penso che questo ti aiuterà. Stai facendo qualcosa di complesso.
Sembra che stia chiedendo al tuo comparatore di implementare l'interfaccia non generica IEqualityComparer
, mentre il tuo implementa IEqualityComparer (Of Object)
, che è un'interfaccia diversa.
Sembra che tu stia usando un database come back-end. non puoi fornire un comparatore personalizzato per questo, poiché non può essere mappato su TSQL.
Hai provato Contiene
? cioè dove! List1.Contains (i.SiteID)
?