LINQ 除了使用自定义比较器

发布于 2024-07-24 11:42:41 字数 1338 浏览 8 评论 0原文

我尝试在 LINQ 结果集上使用“Except”方法,使用自定义实现 if 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'"

任何人都可以解释一下为什么会这样。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

旧城烟雨 2024-07-31 11:42:41

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

我认为您的选择是:

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

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.
不打扰别人 2024-07-31 11:42:41

使用以下代码。

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

这是基于不符合条件的情况。 我想这会对你有帮助。 你正在做一些复杂的事情。

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.

时光病人 2024-07-31 11:42:41

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

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.

饮湿 2024-07-31 11:42:41

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

您尝试过包含吗? 即哪里!List1.Contains(i.SiteID)

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文