2013-03-02 4 views
1

Je veux faire un LINQ NOT EXISTS sur requête MULTIPLE TABLES.Linq NOT EXISTS plusieurs tables

Tous les exemples sur Google ou SO traitent deux tables Je travaille avec trois donc je me bats comme un débutant sur LINQ sur la façon de les référencer correctement.

Tout d'abord j'ai essayé cette requête LINQ

var nocertificates = (
    from x in rmdb.t_certificates 
    from ce in rmdb.t_user_certificates 
    from u in rmdb.t_users 
    where u.id == ce.uid && ce.value != x.id 
    select x).AsEnumerable().Select(x => new ViewModelCheckBox() 
     { 
     Value = x.id.ToString(), 
     Name = x.name, 
     Checked = false 
     }); 

je les trois fois laid de comme je ne suis pas bon avec la création de types pour y adhérer. Mais cela a donné un mauvais résultat et je compris que je devais aller pour un PAS EXISTE

Je construit une nouvelle requête en T-SQL

Ceci est la requête SQL cela fonctionne!

select distinct * from t_certificates tc 
where NOT EXISTS 
(
select distinct * from t_users tu, t_user_certificates tuc 
WHERE tu.email = '[email protected]' 
and tu.id = tuc.[uid] 
and tuc.value = tc.id 
) 

Comment ferais-je cela dans LINQ?

C'est la question, j'accorderai ma réponse pour cela!

BUT!

Quand nous y sommes ... Je suis vraiment curieux de la réponse .. Est-il possible de faire une requête LINQ qui retourne un IEnumerable à la fois ceux qui EXISTS et NOT EXISTS résultant dans un objet qui contiendra VALEURS différentes sur la propriété checked
EXISTE -> checked = true
NOT EXISTS -> vÉRIFIÉ = false

Voilà comment je crée mon objet.

.Select(x => new ViewModelCheckBox() 
     { 
     Value = x.id.ToString(), 
     Name = x.name, 
     Checked = this should be different based on exists or not 
     }); 
+2

Pour votre deuxième question: Conceptuallly c'est juste une jointure externe gauche avec une clause WHERE qui sélectionne uniquement les enregistrements avec un champ non annulable de la table de droite étant NULL. –

Répondre

2

La réponse LINQ devrait ressembler à ceci (non testé):

var nocertificates = 
    from x in rmdb.t_certificates 
    join tuc in (
    from u in rmdb.t_users 
    join ce in rmdb.t_user_certificates on u.id == ce.uid 
    select ce.value 
) on tuc.value = tc.id into tuc 
    from y in tuc.DefaultIfEmpty() 
    where y == null 
    select x; 
+0

Hmmm quelque chose de mal, les tableaux ne sont pas cohérents ... J'ai utilisé d'autres noms pour linq et SQL :(Je me trompe de portée ... – 8bitcat

2

C'est ce que je fini par utiliser!

var query = (from tc in rmdb.t_certificates 
      where !(
        from tu in rmdb.t_users 
        from tuc in rmdb.t_user_certificates 
        where tu.email == username 
        && tu.id == tuc.uid 
        && tuc.value == tc.id select tc).AsEnumerable().Any() 
        select new ViewModelCheckBox() 
           { Checked = false, 
            intconverter = tc.id, 
            Name = tc.name 
           }); 
Questions connexes