【问题标题】:LINQ Except using custom ComparerLINQ 除了使用自定义比较器
【发布时间】:2010-11-03 15:28:59
【问题描述】:

如果 IEqualityComparer 根据结果集中单个字段的值排除某些结果,我正在尝试使用自定义实现对 LINQ 结果集使用“Except”方法。

所以,简而言之,我有...

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

谁能解释一下为什么会这样。

【问题讨论】:

  • 是的,这就是我开始的地方,但我遇到了同样的错误。我假设因为它说它不能按类转换为“System.Collections.Generic.IEqualityComparer”这就是它想要的?

标签: vb.net linq iequalitycomparer except


【解决方案1】:

您的问题是您实现了 IEqualityComparer(Of Object),但您的列表是 List(Of AT),其中 AT 是匿名类型,因此您无法实现 IEqualityComparer(Of AT)。

我认为你的选择是:

  1. 声明一个类/结构来保存 SideID/SiteName,并选择该类的一个实例,然后实现 IEqualityComparer(Of NewClass)。
  2. 使用后期绑定调用(即选项显式关闭,就像您现在正在做的那样),并在调用 except 之前在两个列表上放置一个 .Cast(Of Object)() 调用。

【讨论】:

  • 谢谢乔纳森。我确实在早期确实考虑过对结构进行显式转换,但在修复其他错误后并没有坚持下去!我想唯一的问题是必须使结构与您的 LINQ 结果数据字段保持同步 - 不过没什么大不了的。
【解决方案2】:

使用以下代码。

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

这是基于不在状态。我想这会对你有所帮助。你正在做一些复杂的事情。

【讨论】:

  • 啊哈!这看起来更像是我更熟悉的 SQL。我试图弄清楚如何做一个“WHERE SiteID NOT IN(SELECT SiteID FROM ....)”。谢谢。
  • 实际上并没有回答我原来的问题,但确实让我到达了我想去的地方:-)
【解决方案3】:

看起来它要求您的比较器实现非通用接口IEqualityComparer,而您的实现IEqualityComparer (Of Object),这是一个不同的接口。

【讨论】:

    【解决方案4】:

    看起来您正在使用数据库作为后端。您不能为此提供自定义比较器,因为它无法映射到 TSQL。

    你试过Contains吗?即where !List1.Contains(i.SiteID)?

    【讨论】:

    • 你能在匿名类型集合的元素上使用 .Contains 吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-21
    • 2017-11-02
    • 2018-10-31
    • 1970-01-01
    相关资源
    最近更新 更多