LINQ Кроме использования пользовательского Comparer - PullRequest
2 голосов
/ 17 июня 2009

Я пытаюсь использовать метод «Кроме» в наборе результатов LINQ, используя пользовательскую реализацию, если IEqualityComparer исключает определенные результаты на основе значения одного поля из набора результатов.

Итак, в упрощенном виде я ...

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

Мой компаратор выглядит следующим образом ...

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

Я получаю недопустимое исключение приведения в строке ".Except" с сообщением "Невозможно привести объект типа" ... insCompare "к типу" System.Collections.Generic.IEqualityComparer '"

Может кто-нибудь пролить свет на то, почему это может быть, пожалуйста.

Ответы [ 4 ]

2 голосов
/ 17 июня 2009

Используйте следующий код.

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

это основано на не в состоянии. Я думаю, что это поможет вам. Вы делаете что-то сложное.

2 голосов
/ 17 июня 2009

Ваша проблема здесь в том, что вы реализуете IEqualityComparer (Of Object), но ваши списки - это List (Of AT), где AT - анонимный тип, поэтому вы не можете реализовать IEqualityComparer (Of AT).

Я думаю, что ваш выбор:

  1. Объявите класс / структуру для хранения SideID / SiteName и выберите экземпляр этого класса, затем реализуйте IEqualityComparer (Of NewClass).
  2. Используйте вызовы с поздним связыванием (т. Е. Параметр явно отключен, как, кажется, вы делаете сейчас) и поместите вызов .Cast (Of Object) () в оба списка перед вызовом Except.
1 голос
/ 17 июня 2009

Похоже, вы используете базу данных в качестве серверной части. Вы не можете предоставить для этого собственный компаратор, поскольку он не может быть сопоставлен с TSQL.

Вы пробовали Contains? то есть where !List1.Contains(i.SiteID)?

1 голос
/ 17 июня 2009

Похоже, он просит ваш компаратор реализовать неуниверсальный интерфейс IEqualityComparer, тогда как ваш реализует IEqualityComparer (Of Object), который является другим интерфейсом.

...