3

我是Linq noobie,也许有人可以指出我正确的方向。这里有什么问题?这些匿名类型似乎具有相同的签名。

          '*** Get all of the new list items'
          Dim dsNewFiles = From l1 In list1 _
                           Where Not (From l2 In list2 _
                                      Select l2.id, l2.timestamp).Contains(New With {l1.id, l1.timestamp})

我希望在上面的代码中有一些突出显示的方法,但是我得到了编译错误:

Value of type '<anonymous type> (line n)' cannot be converted to '<anonymous type> (line n)'.

在“.Contains( New With{l1.id, l1.timestamp} )”

我假设它认为匿名类型在某种程度上是不同的,但是 id 和 timestamp 列在任一列表中都是相同的。它们的顺序也相同。两者之间还有什么不同?

[编辑 2009 年 7 月 10 日 16:28 EST]

我尝试了用户 Meta-Knight 的建议代码(使用 {Key l1.id, l1.timestamp} 新建),它修复了编译错误。但是,当我使用 List1 和 List2 运行代码时,如下所示:

List1                         List2
id     timestamp              id     timestamp
--     ----------             --     ----------
01     2009-07-10 00:00:00    01     2009-07-10 00:00:00

结果是:

dsNewFiles
id     timestamp
--     ----------
01     2009-07-10 00:00:00

它应该是一个空列表。

4

2 回答 2

1

当您生成匿名类型时,如果它们没有以相同的名称和相同的确切顺序指定它们的属性,它们将作为单独的类型生成。所以你的例子和我这样做是一样的:

Class A 
BeginClass 
    Begin ID as Int Begin ... End 
    Stuff as String Begin ... End 
EndClass

Class B 
BeginClass 
    Begin Stuff as String Begin ... End 
    ID as Int Begin ... End 
EndClass

From a In someListofAs
Where Not (From b In someListofBs Select b).Contains(a)

这是完整的空气代码,顺便说一句。

此外,在您的示例中,您的 LINQ 的一部分是匿名类型,而另一部分不是。那可能是你的问题。

试试这个:

From l1 In list1 _
Where Not (From l2 In list2 _
    Select New With { ID = l2.id, Timestamp = l2.timestamp}).Contains(
        New With { ID = l1.id, Timestamp = l1.timestamp})
于 2009-07-09T16:45:46.963 回答
1

只需将代码的最后一部分更改为:

New With {Key l1.id, Key l1.timestamp}

我测试了代码,它可以工作。

编辑:

我不知道为什么这对您不起作用,我将发布整个代码以确保安全。

Dim dsNewFiles = From l1 In list1 _
                           Where Not (From l2 In list2 _
                                      Select l2.ID, l2.TimeStamp).Contains(New With {Key l1.ID, Key l1.TimeStamp})

另一种选择是简单地执行以下操作:

Dim dsNewFiles = list1.Except(list2)

为此,您的类必须重写 Equals 和 GetHashCode,并实现 IEquatable(Of T) 接口。MSDN 上有一个很好的例子(在底部)。

如果 ID 和 Timespan 在您的类中不代表相等,您可以使用自定义 IEqualityComparer(Of T) 作为第二个参数。

于 2009-07-09T21:12:58.017 回答