Linq To Sql : Requete Dynamique [Résolu]

cs_suzukMan 58 Messages postés mercredi 25 avril 2007Date d'inscription 13 septembre 2012 Dernière intervention - 19 janv. 2011 à 14:19 - Dernière réponse : cs_suzukMan 58 Messages postés mercredi 25 avril 2007Date d'inscription 13 septembre 2012 Dernière intervention
- 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
Afficher la suite 

Votre réponse

7 réponses

Meilleure réponse
nhervagault 6069 Messages postés dimanche 13 avril 2003Date d'inscription 15 juillet 2011 Dernière intervention - 25 janv. 2011 à 16:28
3
Merci
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

Merci nhervagault 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 93 internautes ce mois-ci

Commenter la réponse de nhervagault
Shaolyne 155 Messages postés jeudi 12 mai 2005Date d'inscription 8 mars 2011 Dernière intervention - 20 janv. 2011 à 09:25
1
Merci
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.
Commenter la réponse de Shaolyne
nhervagault 6069 Messages postés dimanche 13 avril 2003Date d'inscription 15 juillet 2011 Dernière intervention - 19 janv. 2011 à 23:40
0
Merci
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
Commenter la réponse de nhervagault
nhervagault 6069 Messages postés dimanche 13 avril 2003Date d'inscription 15 juillet 2011 Dernière intervention - 20 janv. 2011 à 09:35
0
Merci
Il me semble que le contains est l'équivalent du like '%'+@pays+'%'

comme like '%FR%'
Commenter la réponse de nhervagault
cs_suzukMan 58 Messages postés mercredi 25 avril 2007Date d'inscription 13 septembre 2012 Dernière intervention - 25 janv. 2011 à 16:08
0
Merci
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
Commenter la réponse de cs_suzukMan
Shaolyne 155 Messages postés jeudi 12 mai 2005Date d'inscription 8 mars 2011 Dernière intervention - 25 janv. 2011 à 16:41
0
Merci
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.
Commenter la réponse de Shaolyne
cs_suzukMan 58 Messages postés mercredi 25 avril 2007Date d'inscription 13 septembre 2012 Dernière intervention - 27 janv. 2011 à 12:32
0
Merci
Bonjour,

Excellent Merci !!


Cordialement
Commenter la réponse de cs_suzukMan

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.