2009-07-09 10 views
3

Je suis un Linq noobie, peut-être que quelqu'un peut me diriger dans la bonne direction. Quel est le problème ici? Ces types anonymes semblent avoir les mêmes signatures.Linq, VB - Type anonyme ne peut pas être converti en type anonyme

  '*** 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}) 

Je souhaite qu'il y avait un moyen de mettre en évidence dans le code ci-dessus, mais je reçois l'erreur de compilation:

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

sur la » .Contains (Nouveau Avec {l1.id, l1. horodatage}) "

Je suppose qu'il pense que les types anonymes sont différents d'une certaine façon, mais les colonnes id et timestamp sont les mêmes dans les deux listes. Ils sont également dans le même ordre. Quoi d'autre peut être différent entre les deux?

[Modifier 7/10/2009 16:28 EST]

I Tried le code suggéré de l'utilisateur Meta-Knight (Nouveau avec la {l1.id Key, l1.timestamp}) et il a fixé la erreur de compilation. Cependant, quand je courais le code avec List1 et List2 comme suit:

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

Le résultat a été:

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

Il aurait dû être une liste vide.

Répondre

1

il suffit de changer la dernière partie de votre code:

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

J'ai testé le code et cela fonctionne.

Edit:

Je ne sais pas pourquoi cela ne fonctionne pas pour vous, je posterai tout le code juste pour être sûr.

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

Une autre option est de faire simplement ce qui suit:

Dim dsNewFiles = list1.Except(list2) 

Pour que cela fonctionne, votre classe doit passer outre Equals et GetHashCode, et mettre en œuvre l'interface IEquatable (Of T). Il y a un très bon exemple on MSDN (en bas).

Si ID et Timespan ne représentent pas l'égalité dans votre classe, vous pouvez utiliser un IEqualityComparer (Of T) personnalisé comme deuxième argument.

+0

@ Meta-Knight: Merci pour la perspicacité. L'erreur de compilation est partie. Cependant, le code ne fonctionne toujours pas comme prévu. S'il vous plaît voir la modification ci-dessus. – Daniel

+0

J'ai édité avec plus de détails et une autre alternative. –

1

Lorsque vous générez des types anonymes, ils sont générés en tant que types distincts s'ils ne spécifient pas leurs propriétés avec le même nom et dans le même ordre. Donc, votre exemple est le même que si je l'ai fait:

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) 

C'est le code aérien complet, btw.

En outre, dans votre exemple, une partie de votre LINQ est un type anonyme et l'autre ne l'est pas. Cela pourrait être votre problème.

Essayez ceci:

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}) 
+0

Ah. Je vois. Une idée de comment faire ce que j'essaye de faire là? – Daniel

+0

Je vois votre édition là ... Je ne pense pas que cela fonctionnera, au moins, il ne semble pas l'être. N'est-ce pas le même cas que ci-dessus? Les deux nouveaux "Withs" créeront des objets de signatures différentes? – Daniel

+0

@hypoxide Aucune des deux signatures ne me ressemble. Sauf si j'ai mal saisi quelque chose que je ne vois pas. Essayez-le et voyez ce que vous obtenez, je n'ai pas VS devant moi sinon j'essaierais. – Joseph

Questions connexes