我是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)'.
on“.Contains( New With {l1.id,l1.timestamp} )”
我认为它认为匿名类型在某种程度上是不同的,但id和timestamp列在任一列表中都是相同的。它们的顺序也是一样的。两者之间还有什么不同?
[编辑7/10/2009 16:28 EST]
我尝试了用户Meta-Knight(New With {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
它应该是一个空列表。
答案 0 :(得分: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})
答案 1 :(得分: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)接口。有一个很好的例子on MSDN(在底部)。
如果ID和Timespan在您的类中不表示相等,则可以使用自定义IEqualityComparer(Of T)作为第二个参数。