Reputation: 11054
I'm a Linq noobie, maybe someone can point me in the right direction. What's wrong here? These anonymous types seem to have the same signatures.
'*** 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})
I wish there were some way to highlight in the above code, but I get the compile error:
Value of type '<anonymous type> (line n)' cannot be converted to '<anonymous type> (line n)'.
on the ".Contains(New With{l1.id, l1.timestamp})"
I assume it thinks the anonymous types are different in some way, but the id and timestamp columns are the same in either list. They are also in the same order. What else can be different between the two?
[Edit 7/10/2009 16:28 EST]
I tried the suggested code from user Meta-Knight (New With {Key l1.id, l1.timestamp}) and it fixed the compile error. However, when I ran the code with List1 and List2 as follows:
List1 List2
id timestamp id timestamp
-- ---------- -- ----------
01 2009-07-10 00:00:00 01 2009-07-10 00:00:00
The result was:
dsNewFiles
id timestamp
-- ----------
01 2009-07-10 00:00:00
It should have been an empty list.
Upvotes: 3
Views: 4400
Reputation: 17845
Just change the last part of your code to:
New With {Key l1.id, Key l1.timestamp}
I tested the code and it works.
Edit:
I don't know why this doesn't work for you, I'll post the whole code just to be sure.
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})
Another option is to simply do the following:
Dim dsNewFiles = list1.Except(list2)
For this to work, your class must override Equals and GetHashCode, and implement the IEquatable(Of T) interface. There's a very good example on MSDN (at the bottom).
If ID and Timespan don't represent equality in your class, you can use a custom IEqualityComparer(Of T) as a second argument.
Upvotes: 1
Reputation: 25513
When you generate anonymous types, they will be generated as separate types if they don't specify their properties with the same name and in the same exact order. So your example is the same as if I did this:
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)
That's complete air code, btw.
Also, in your example one part of your LINQ is an anonymous type and the other isn't. That might be your problem.
Try this:
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})
Upvotes: 1