Linq To Sql : Requete Dynamique

Résolu
cs_suzukMan Messages postés 58 Date d'inscription mercredi 25 avril 2007 Statut Membre Dernière intervention 13 septembre 2012 - 19 janv. 2011 à 14:19
cs_suzukMan Messages postés 58 Date d'inscription mercredi 25 avril 2007 Statut Membre Dernière intervention 13 septembre 2012 - 27 janv. 2011 à 12:32
Bonjour,

Je cherche désperemment comment construire une requete dynamique avec Linq.
Imaginez la fonction suivante :

getAllEmploye(string nom, string pays, char sexe, int idSociete)
{
DataContextGlobal db = new DataContextGlobal(connexion);
var rqt = from e in db.TableEmploye where if nom != "" e.nom.contains(nom) and if....
}

Comment faire ça ?
Sachant que je ne veux pas récuperer toutes mais données et les traités en Linq To Entitys
du genre ça: (je ne trouve pas sa propre)
var list = db.TableEmploye
if nom !"" list list.Where(e=> e.nom.Contains(nom))
if pays !"" list list.Where(e=> e.pays.Contains(pays) ...

Je ne veux pas car il me faut spécifier le maximun de critère pour ma requete afin de ramener le moins de résultat et d'être plus performant.

En ésperant avoir été clair merci d'avance de votre aide.
Cordialement

7 réponses

nhervagault Messages postés 6063 Date d'inscription dimanche 13 avril 2003 Statut Membre Dernière intervention 15 juillet 2011 37
25 janv. 2011 à 16:28
Tu n'as pas compris ce que je voulais démontrer.


var q = from e in ...
        select e


if ( pays !string.empty)  q from e in q where e.pays = pays.contaisn(pays.name) select e
if ( ville!string.empty)  q from e in q where e.ville = ville.contaisn(ville.name) select e
..etc...


L'execution de la requete linq etant tardive,
c'est a dire à l'appel du toList() par exemple

on la construit en concaténant les query
et l'execution se chargera de mettre tout en place

ici le code reelement executé sera
on considere que les where sont dans une collection unique
from e in q 
where e.ville = ville.contaisn(ville.name)
&& e.pays = pays.contaisn(pays.name) 
 select e
3
Shaolyne Messages postés 155 Date d'inscription jeudi 12 mai 2005 Statut Membre Dernière intervention 8 mars 2011 1
20 janv. 2011 à 09:25
Bien le bonjour,

Tout d'abord, est-ce que tes critères doivent être appliqués sur une seule entité (TableEmploye) ou plusieurs?
Dans le cas d'entités multiples, tu peux faire des jointures (cfr. doc MS)

Par contre, je remarque que tu vérifies, dans ta requete LinQ, que tes paramètres (de la méthode) nom et pays sont != null et non vides. A mon sens, ce test doit être effectué en "pré-condition", en dehors de ta requête LinQ en base, comme ceci:
GetAllEmploye(string nom, string pays, char sexe, int idSociete) 
{
   if(String.IsNullOrEmpty(nom) || String.IsNullOrEmpty(pays))
      return ...;  //Dépéndant de ton type de retour de la méthode.
  
   DataContextGlobal db....
}

Ensuite, il te suffit de faire une requête "classique" comme ceci:
GetAllEmploye(string nom, string pays, char sexe, int idSociete) 
{ 
   //pré-conditions

   DataContextGlobal db = new DataContextGlobal(connexion); 
   var rqt = from emp in db.TableEmploye
             where (e.nom != null && e.nom.Contains(nom))
                   && (e.pays != null && e.pays.Contains(pays))
                   ...
             select emp
} 

Encore une question, pourquoi utilises-tu des Contains? Quel est l'équivalent de ta requête en SQL?

Juste pour info, il faut garder en tête quelques considérations lorsqu'on utilise les ORMs MS. Ce billet éclaircira peut-être quelques lecteurs.
En étant attentif, tu devrais remarquer que ta requête initiale est exécutée en partie coté client alors qu'elle pourrait l'être intégralement côté serveur.

Shao.
1
nhervagault Messages postés 6063 Date d'inscription dimanche 13 avril 2003 Statut Membre Dernière intervention 15 juillet 2011 37
19 janv. 2011 à 23:40
Salut,

Il faut utiliser linq de maniere la plus simple possible
comme linq compile et execute la requete a la derniere minute tu as une requete correcte

var q = from e in ...
        select e


if ( pays !string.empty)  q from e in q where e.pays = pays.contaisn(pays.name) select e
......



un autre exemple ici

bon dev
0
nhervagault Messages postés 6063 Date d'inscription dimanche 13 avril 2003 Statut Membre Dernière intervention 15 juillet 2011 37
20 janv. 2011 à 09:35
Il me semble que le contains est l'équivalent du like '%'+@pays+'%'

comme like '%FR%'
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_suzukMan Messages postés 58 Date d'inscription mercredi 25 avril 2007 Statut Membre Dernière intervention 13 septembre 2012 1
25 janv. 2011 à 16:08
Bonjour,

Merci à tous vos réponses et pardon de revenir un peu tardivement sur le sujet, j'ai eu quelques indisponibilités bref ...

Pour répondre à nhervagault

Cela peut fonctionner mais imagine si j'ai 8 paramètre le nombre de test à faire ...
If nom != "" && prenom != "" && sexe!=''
query select [...] where t.nom == this.nom && t.prenom == this.prenom && t.sexe == this.sexe

If nom!= "" && prenom!="" && sexe==""
query select [...] where t.nom = this.nom && t.prenom == this.prenom
C'est juste un exemple pour voir la limite du PB.
--------------------------------------------------------------------------
Pour répondre à Shaolyne

Je ne pense pas que tu es bien compris ce que je demandais (ou je l'ai mal exprimé) je veux dans un cas ou une variable et NULL ou égal à rien (peut importante c'est à titre d'exemple) ne pas éffectuer le critère dans ma requête.
paramètre nom égal nul donc il n'est pas un critère à ma requête.

Pour ce qui est du Contains il sert pour faire un like '%@p%' nhervagault mais un également un sous select genre "nom IN(select nom from prospect)" qui au passage est traduit diffèremment par LINQ.
Au lieu du "IN" il traduit sa par un IF EXIST( SELECT 1 FROM t1, t2, WHERE t1.ID = T2.ID)

Ton article est intéressant mais j'ai pas trouvé de relation avec mon POST ...
-------------------------------------------------------------------------------

Pour du requetage dynamique j'ai trouvé une piste mais elle ne me plait pas trop, c'est écrire sa condition dans une chaîne (avec un StringBuilder par exemple) et faire db.table.Where(stringBuilder) ou db.Table.Where("t2 == t1") ...

Ou même écrire toute sa requête et utiliser une méthode CreateQuery() j'ai pas bien regardé encoire mais un truc du genre .... Dans ces solutions je trouve que l'on sort de l'interêt de Linq.


Cordialement
0
Shaolyne Messages postés 155 Date d'inscription jeudi 12 mai 2005 Statut Membre Dernière intervention 8 mars 2011 1
25 janv. 2011 à 16:41
J'appuie la réponse de nhervagault.
Dans ton cas, tu auras quelque chose comme ceci:
var q = from e in db.TableEmploye
        select e

if ( !String.IsNullOrEmpty(nom) )  q from e in q where e.nom nom select e
if ( !prenom.IsNullOrEmpty(prenom) )  q from e in q where e.prenom prenom select e
if ....


Comme l'a bien dit nhervagault, tu n'auras qu'une seule requête émise à la db, requête contenant tous les critères respectant les conditions des différents if.

Shao.
0
cs_suzukMan Messages postés 58 Date d'inscription mercredi 25 avril 2007 Statut Membre Dernière intervention 13 septembre 2012 1
27 janv. 2011 à 12:32
Bonjour,

Excellent Merci !!


Cordialement
0
Rejoignez-nous