LINQ(カスタム比較を使用する場合を除く)
-
06-07-2019 - |
質問
" 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)
My 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
" .Except"で無効なキャスト例外を受け取ります。 "タイプ '... insCompare'のオブジェクトをタイプ 'System.Collections.Generic.IEqualityComparer'"にキャストできません
誰がこれが喜ばれるのか、理由を明らかにすることができます。
解決
ここでの問題は、IEqualityComparer(Of Object)を実装しますが、リストはList(Of AT)で、ATは匿名型であるため、IEqualityComparer(Of AT)を実装できないことです。
選択肢は次のとおりです:
- SideID / SiteNameを保持するクラス/構造体を宣言し、そのクラスのインスタンスを選択して、IEqualityComparer(Of NewClass)を実装します。
- レイトバウンドコールを使用して(つまり、現在明示的にオフになっているオプション)、Exceptを呼び出す前に両方のリストに.Cast(Of Object)()コールを配置します。
他のヒント
次のコードを使用します。
from t in db.Sites
where
!
(from t0 in db.Sites2
select new {
t0.SomeID
}).Contains(new { t.SomeID })
select t
これは非条件に基づいています。これはあなたの役に立つと思います。 Uは複雑なことをしています。
比較子が非ジェネリックインターフェイス IEqualityComparer
を実装することを要求しているように見えますが、別のインターフェイスである IEqualityComparer(Of Object)
を実装しています。
データベースをバックエンドとして使用しているようです。 TSQLにマッピングできないため、このためのカスタム比較演算子を提供することはできません。
Contains
を試しましたか?つまり、 where!List1.Contains(i.SiteID)
?