IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Linq Discussion :

[C#][Linq]Différence de procédure


Sujet :

Linq

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre très actif
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    612
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juin 2008
    Messages : 612
    Par défaut [C#][Linq]Différence de procédure
    Bonjour,

    Je sais qu'il y a des "pointures" linq sur ce forum. Quelqu'un peut-il donc me dire pourquoi cette méthode fonctionne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
                var clients =
                    (from c in formMDI.Bdd.Client
                     select c).ToList();
     
                var listeClients =                                      // rechercher tous les clients pas encore utilisés
                    (from c in clients
                     where !c.EstDansLeTableau(tabl1)
                     && !c.EstDansLeTableau(tabl2)
                     orderby c.NumClient
                     select c).ToList();
    Mais pas celle-ci ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
                var listeClients2 =
                    (from c in formMDI.Bdd.Client
                     where !c.EstDansLeTableau(tabl1)
                     && !c.EstDansLeTableau(tabl2)
                     orderby c.NumClient
                     select c).ToList();
    dans le second cas, j'obtiens une erreur :

    LINQ to Entities ne reconnaît pas la méthode « Boolean EstDansLeTableau(FactuLite.Client, System.String[]) », et cette dernière ne peut pas être traduite en expression de magasin.
    Y a-t-il une solution pour éviter de créer une liste avec tous les éléments de la table avant de faire la recherche?

    Pour information, voici la méthode "EstDansLeTableau", qui est toute bête :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
            public static bool EstDansLeTableau(this Client client, string[] tableau)
            {
                bool result = false;                        // valeur de retour
                if (tableau != null)
                {
                    long NumTableau;                            // un numéro du tableau
                    long numClient = client.NumClient;          // récupérer numéro du client
     
                    foreach (var item in tableau)
                    {
                        long.TryParse(item, out NumTableau);    // tenter la conversion de l'élément en long
                        if (numClient == NumTableau)            // si ce numéro est celui du client
                        {
                            result = true;                      // on a trouvé
                            break;                              // et fin de la recherche
                        }
                    }
                }
                return result;
            }
    Merci d'avance

    Claude

  2. #2
    Rédacteur
    Avatar de The_badger_man
    Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2005
    Messages
    2 745
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 745
    Par défaut
    est de quelle nature ?

    Si c'est une entité Linq (mappée à une table) alors je pense que la réponse est la suivante:

    Dans le premier cas tu fais une requête qui va être traduite en SQL par Linq to Entities. Puis tu fais un ToList qui va executer cette requête et ramener des objets.
    Puis tu utilises EstDansLeTableau sur le résultat de la requête précédente, et là tu travailles sur des objets en mémoire: Linq to Object.


    Dans le deuxième cas tu essayes de tout faire d'un coup. Linq to Entities essaye donc de traduire la requête en SQL. Et il plante parcequ'il ne sait pas traduire ta fonction EstDansLeTableau en SQL.
    Les règles du forum
    Le trio magique : FAQ + Cours + fonction rechercher
    Mes articles
    Pas de questions par messages privés svp

    Software is never finished, only abandoned.

  3. #3
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    - 1ere méthode : tu effectues la 1ere requête sur la base de données et tu transformes le résultat en List<Client>. La 2e requête Linq ne travaille donc plus sur un IQueryable<Client> mais sur un IEnumerable<Client>, donc la requête n'est pas transformée en SQL pour être exécutée sur la base, et l'appel à EstDansLeTableau se passe bien

    - 2e méthode : tu travailles directement sur un IQueryable, sans conversion intermédiaire en IEnumerable, donc Linq essaie de transformer ta requête en SQL, mais comme la fonction EstDansLeTableau n'existe pas en SQL, ça plante...

  4. #4
    Rédacteur
    Avatar de The_badger_man
    Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2005
    Messages
    2 745
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 745
    Par défaut
    A part tes mots savants, c'est ce que j'ai dit
    Les règles du forum
    Le trio magique : FAQ + Cours + fonction rechercher
    Mes articles
    Pas de questions par messages privés svp

    Software is never finished, only abandoned.

  5. #5
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Citation Envoyé par The_badger_man Voir le message
    A part tes mots savants, c'est ce que j'ai dit

    en fait j'avais pas vu ton message quand j'ai posté...

  6. #6
    Membre très actif
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    612
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juin 2008
    Messages : 612
    Par défaut
    Bonjour,

    Merci, les deux explications sont limpides.

    Si j'ai bien compris les implications :

    1) Il m'est impossible d'intégrer ce genre de fonction dans une requête linq portant sur une table sqLite

    2) La seule façon de procéder, si je veux éviter de rapatrier l'intégralité de la table en RAM serait donc de parcourir la table et de faire le tri dans un foreach, au lieu d'utiliser ToList. Si j'ai tout saisi, c'est justement ce que fait une requête suivie d'un ToList : une sélection au moment du parcours des éléments de la table :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
     
    var query =
        from c in formMDI.Bdd.Client.Include("Adresse")
        orderby c.NumClient
        select c;
     
    var listeClients = new List<Client>();          // créer une liste de clients
    foreach (var client in query)                   // parcourir la table
        if (!client.EstDansLeTableau(tabl1))        // si le client n'est utilisé dans aucune des zones texte in et out
            if (!client.EstDansLeTableau(tabl2))
                listeClients.Add(client);           // l'ajouter dans la liste des clients à afficher

    C'est bien ça, où il y a une méthode plus simple?

    J'allais dire que ce n'était pas dérangeant pour sqLite qui travaille en local, mais que ramener tous les éléments à partir d'un serveur était lourd, quand je me suis rappelé que sqLite ne permet pas de stocker des procédures, mais sql serveur si. Serait-ce la raison de cette différence?

    Merci
    Claude

    --------------

  7. #7
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Ben fait s'il y a des critères qui te permettent de pré-filtrer les données directement en SQL, tu peux les utiliser, faire le ToList sur le résultat, et ensuite filtrer selon ta fonction EstDansLeTableau.

    Par contre, j'ai une info qui devrait te plaire

    Avec SQLite, tu peux définir des fonctions en C# (ou en C, ou n'importe quel langage à partir duquel tu utilises SQLite) et les "mapper" avec un nom de fonction utilisable en SQL. J'avais testé ça il y a quelque temps, j'essaierai de te retrouver le code.

    Par contre je suis pas sûr que le provider EF de SQLite soit capable de réaliser que tu as mappé la méthode C# avec une fonction SQL... en fait, en y réfléchissant un peu ça parait même peu probable

Discussions similaires

  1. linq to sql, procédure stockée
    Par solo190 dans le forum C#
    Réponses: 0
    Dernier message: 01/09/2011, 11h57
  2. Différence de procédures FASM/TASM
    Par CP / M dans le forum Assembleur
    Réponses: 3
    Dernier message: 30/07/2008, 15h17
  3. Différence entre macros et procédures ?
    Par noubigh dans le forum Assembleur
    Réponses: 7
    Dernier message: 11/02/2007, 00h12
  4. Mysql5: différences entre procédures et fonctions
    Par El Riiico dans le forum SQL Procédural
    Réponses: 1
    Dernier message: 25/11/2005, 05h43
  5. Différence, exemple procédural, événementiel, objet ?
    Par ludophil dans le forum Débuter
    Réponses: 3
    Dernier message: 26/10/2005, 08h35

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo