2009-05-18 8 views
0

J'ai la structure classique 3 table - entity, tag et entitytag - base de données.Linqtosql - Trouver toutes les entités correspondant à tous les tags dans une requête

Afin de trouver toutes les entités taggés avec certaines balises J'utilise le code LinqToSql suivant:

string[] myTags = {"tag1","tag2"}; 

var query = from m in entity 
      where m.entitytag.Where(c => myTags.Contains(c.tag.TagName)).Count() == myTags.Count() 
      select m; 

Cependant, lorsque les entités ont des balises en double (il y a une raison valable pour cela dans mon application réelle) la La requête renvoie des entités qui ne correspondent pas à toutes les balises. Par exemple, dans l'exemple de code ci-dessus, si une entité était étiquetée deux fois avec 'tag1' et non 'tag2', elle retournerait dans les résultats, bien qu'elle ne corresponde pas aux deux étiquettes.

Je n'arrive pas à comprendre comment exclure ces entités des résultats?

Ou y a-t-il une approche complètement différente que je devrais prendre?

Répondre

0

Comme suggéré par Eoin, Distinct() doit être utilisé, mais il ne fonctionne pas contre des ensembles complets de entitytag. Utiliser une autre instruction Select pour comparer uniquement avec la balise réelle est l'astuce ici.

string[] myTags = {"tag1","tag2"}; 

    var query = from m in entity 
    where m.entitytag.Select(et => et.tag.TagName).Distinct().Where(c => myTags.Contains(c)).Count() == myTags.Count() 
    select m; 

Malheureusement, l'inconvénient est que cela nuit quelque peu à la performance.

0

Que diriez-vous de changer à

where m.entitytag.Distinct().Where(c => ... 

qui supprimerait les entitytags en double de votre entité sous-objets collection, et permettre à votre compteur fonctionne correctement

+0

J'ai essayé cela mais il retourne toujours les entrées en double. –

+0

Ajout de Select (et => et.tag.TagName) avant que Distinct fasse ce travail. Voir ma réponse à cette question ... –

1

Essayez cette requête à la place:

    string[] myTags = { "tag1", "tag2" }; 
        var query = from m in entity 
           where myTags.All(tag => m.entitytag.Contains(tag)) 
           select m; 
        query.Dump(); 

La méthode d'extension Tout est ce qui garantira que chaque balise satisfait les critères de contenu.

Il existe également une méthode d'extension Any pour les cas où vous souhaitez qu'un seul critère soit satisfait.

Espérons que ça aide.

Kavan

+0

Ceci n'est pas valide. le 'tag' dans votre clause where est de type string et non entitytag. –

0

Essayez

string[] myTags = { "tag1", "tag2" }; 

var query = from e in entity 
      where !myTags.Except(from e.tag select e.tag.TagName).Any() 
      select e; 

L'idée est de supprimer les balises d'une copie de myTags de l'entité. Tout élément laissé après cela correspond aux balises manquantes dans l'entité.

Je ne sais pas comment cela fonctionne, cependant.

+0

Il vous manque la table entitytag –

Questions connexes