2009-06-17 58 views
2

我想在使用自定義實現的LINQ結果集上使用「Except」方法,如果IEqualityComparer根據結果集中單個字段的值排除某些結果。LINQ除了使用自定義比較器

因此,以簡單的形式我有...

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

我的Comparer是如下...

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 

我上 「除」 行了無效的轉換異常帶消息「無法將類型爲'...比較'的對象類型轉換爲鍵入'System.Collections.Generic.IEqualityComparer'」

有沒有人可以投射爲什麼這可能是請。

+0

是的,這是我開始的地方,但我得到了同樣的錯誤。我認爲,因爲它說它不能通過類來轉換爲「System.Collections.Generic.IEqualityComparer」,這是它想要的? – FourOaks 2009-06-17 12:27:29

回答

2

這裏的問題是你實現IEqualityComparer(Of Object),但是你的列表是List(Of AT),其中AT是一個匿名類型,所以你不能實現IEqualityComparer(Of AT)。

我覺得你的選擇是:

  1. 聲明一個類/結構來保存SideID /網站名稱,並選擇成類的一個實例,然後實現的IEqualityComparer(Of的NewClass)。
  2. 使用延遲調用(即選項顯式關閉,就像它現在所做的那樣),並在調用Except之前在這兩個列表上放置一個.Cast(Of Object)()調用。
+0

謝謝喬納森。我很早就想到了一個明確的演員陣容,但是在我排除其他錯誤之後並沒有對此做出反應!我想唯一的問題是不得不保持結構與LINQ結果數據字段同步 - 但沒有什麼大不了的。啊哈! – FourOaks 2009-06-17 12:40:14

1

它看起來像是要求你的比較器實現非通用接口IEqualityComparer,而你的實現是IEqualityComparer (Of Object),這是一個不同的接口。

1

它看起來像你使用數據庫作爲後端。你不能爲提供一個自定義的比較器,因爲它不能被映射到TSQL。您是否嘗試過Contains?即where !List1.Contains(i.SiteID)

+0

您可以在匿名類型集合的元素上使用.Contains嗎? – FourOaks 2009-06-17 13:00:17

2

使用以下代碼。

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

這是基於不在條件。我認爲這會幫助你。你正在做一些複雜的事情。

+0

啊!這看起來更像是我更熟悉的SQL。我試圖找出如何做一個「WHERE SiteID不在(選擇SiteID從....)」。謝謝。 – FourOaks 2009-06-17 13:04:50