Question

I am trying to use the "Except" method on a LINQ result set using a custom implementation if IEqualityComparer to exclude certain results based on the value of a single field from the result set.

So, in simplified form I have...

'' 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)

My Comparer is as follows...

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

I get an invalid cast exception on the ".Except" line with the message "Unable to cast object of type '...insCompare' to type 'System.Collections.Generic.IEqualityComparer'"

Can anyone cast light on why this might be please.

Was it helpful?

Solution

Your problem here is that you implement IEqualityComparer(Of Object), but your lists are List(Of AT) where AT is an anonymous type, so you can't implement IEqualityComparer(Of AT).

I think your choices are:

  1. Declare a class/struct to hold the SideID/SiteName, and select into an instance of that class, then implement IEqualityComparer(Of NewClass).
  2. Use late-bound calls (ie. option explicit off, like it appears you are doing now), and put a .Cast(Of Object)() call on both lists before calling Except.

OTHER TIPS

Use the following code.

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

this is based in not in condition. I think this will help you. U are doing some complex thing.

It looks like it's asking that your comparer implement the non-generic interface IEqualityComparer, whereas yours implements IEqualityComparer (Of Object), which is a different interface.

It looks like you are using a database as the back end. You can't provide a custom comparer for this, as it can't be mapped to TSQL.

Have you tried Contains? i.e. where !List1.Contains(i.SiteID)?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top