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 :

Récupération d'un résultat d'une requête dans une datatable


Sujet :

Linq

  1. #1
    Membre du Club
    Inscrit en
    Mai 2006
    Messages
    98
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 98
    Points : 53
    Points
    53
    Par défaut Récupération d'un résultat d'une requête dans une datatable
    Bonjour, je début en C# et j'ai besoin de récupérer le résultat d'une requête linq dans une datatable, j'ai utilisé le code suivant:

    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
    21
                   public DataTable resultrequete(DataTable table)
            {
     
     
                var query =
                    from ag in table.AsEnumerable()
                    where ag.Field<string>("Nom").StartsWith("B")
                    select new
                    {
                        Matricule = ag.Field<string>("Matricule"),
                        Nom = ag.Field<string>("Nom"),
                        Prenom = ag.Field<string>("Prenom"),
                        NomCourt = ag.Field<string>("NomCourt")
                    };
     
                DataTable dataresult;
                dataresult = query.CopyToDataTable();
     
                return dataresult ;
     
            }
    en m'inspirant de l'exemple suivant, trouvé sur le site msdn à cette adresse
    http://msdn.microsoft.com/fr-fr/library/bb386921.aspx

    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
    21
    22
    23
    24
    25
    26
    27
    28
    // Fill the DataSet.
    DataSet ds = new DataSet();
    ds.Locale = CultureInfo.InvariantCulture;
    FillDataSet(ds);
     
    DataTable orders = ds.Tables["SalesOrderHeader"];
    DataTable details = ds.Tables["SalesOrderDetail"];
     
    var query =
        from order in orders.AsEnumerable()
        join detail in details.AsEnumerable()
        on order.Field<int>("SalesOrderID") equals
            detail.Field<int>("SalesOrderID")
        where order.Field<bool>("OnlineOrderFlag") == true
        && order.Field<DateTime>("OrderDate").Month == 8
        select new
        {
            SalesOrderID =
                order.Field<int>("SalesOrderID"),
            SalesOrderDetailID =
                detail.Field<int>("SalesOrderDetailID"),
            OrderDate =
                order.Field<DateTime>("OrderDate"),
            ProductID =
                detail.Field<int>("ProductID")
        };
     
    DataTable orderTable = query.CopyToDataTable();
    Mais je récupère l'erreur suivante:
    Le type 'AnonymousType#1' ne peut pas être utilisé comme paramètre de type 'T' dans le type ou la méthode générique 'System.Data.DataTableExtensions.CopyToDataTable<T>(System.Collections.Generic.IEnumerable<T>)'. Il n'y a pas de conversion de référence implicite de 'AnonymousType#1' en 'System.Data.DataRow'.
    J'ai essayé plusieurs alternatives, mais au final je me retrouve toujours bloqué. Pouvez vous me donner de quoi m'aiguiller?

    Merci d'avance.

  2. #2
    Inactif
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    59
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : Algérie

    Informations forums :
    Inscription : Juillet 2009
    Messages : 59
    Points : 73
    Points
    73
    Par défaut Ne pas utiliser le type anonyme var
    Bonjour,
    après avoir regardé ton code, j'ai dégagé deux solutions possibles (à mon sens):
    1. Comme dans la plupart des livres sur le linq (je te conseille de lire linq in action), l'utilisation des types anonymes (var) se restreint aux cas ou l'on sait pas definir le type retourné (il ne s'agit ni d'un datarow ni d'un entier,...). La structure commune utilisée est la suivante:
    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
     
     var resultat = from element in enumerationElement
             join....
             where ....
             select 
             {
                  NomDuChamps= Field<TypeDuChamps>("NomDuChamps"),
                  ....
             };
    //Creation de la table 
    DataTable dt=new DataTable();
     
    //Creation des colonnes de la tables 
    ....
     
    foreach(var result in resultat)
    {
            DataRow row=dt.NewRow();
            row[NomChamps]=result.NomDuChamps;
    }
    de cette façon on obtient à la fin la table issue de la requête Linq.

    2. Comme inscrit dans l'exemple msdn que t'as lu, on peut utiliser IEnumerable<DataRow>. En mettant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    IEnumerable<DataRow> resultat=...
    tu precise à l'avance que le type du resultat de la requete est enumeration. pour que tu comprennes mieux le truc il faut savoir que le linq est implémenté en interne par des extensions et des foreach c'est pour cela d'ailleurs qu'on doit appliquer le from sur un objet enumerable comme NomTable.AsEnumerable().

    et avec cette méthode, et comme l'est stipulé dans l'article msdn, tu peux utiliser la méthode
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    CopyToDataTable<DataRow>()

    j'espère que ceci t'aidera à mieux comprendre cet outil puissant...
    bon courage

  3. #3
    Membre du Club
    Inscrit en
    Mai 2006
    Messages
    98
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 98
    Points : 53
    Points
    53
    Par défaut
    Merci pour la réponse, je teste ça et te tiens au courant.

  4. #4
    Membre du Club
    Inscrit en
    Mai 2006
    Messages
    98
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 98
    Points : 53
    Points
    53
    Par défaut
    Alors j'ai essayé plusieurs choses:

    ceci fonctionne:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
                IEnumerable<DataRow> query = 
                    from ag in table.AsEnumerable()
                    where ag.Field<string>("Nom").StartsWith("B")
                    select  ag;
                datacurrent = query.CopyToDataTable();
    mais pas ça

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
                IEnumerable<DataRow> query = 
                    from ag in table.AsEnumerable()
                    where ag.Field<string>("Nom").StartsWith("B")
                    select  new
                    {
                        Matricule = ag.Field<string>("Matricule"),
                        Nom = ag.Field<string>("Nom"),
                        Prenom = ag.Field<string>("Prenom"),
                        NomCourt = ag.Field<string>("NomCourt")
                    };
     
                datacurrent = query.CopyToDataTable();
    Je vais voir si la partie qui fonctionne me permet d'avancer, même si j'aimerais bien comprendre ce qui ne vas pas dans ce qui ne fonctionne pas :s Quoiqu'il en soit, merci beaucoup pour les conseils

  5. #5
    Inactif
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    59
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : Algérie

    Informations forums :
    Inscription : Juillet 2009
    Messages : 59
    Points : 73
    Points
    73
    Par défaut Ok
    Peux tu m'envoyer ton code (enfin la partie avec laquelle tu exploite le code linq)? je verrai

  6. #6
    Inactif
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    59
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : Algérie

    Informations forums :
    Inscription : Juillet 2009
    Messages : 59
    Points : 73
    Points
    73
    Par défaut Je pense avoir compris
    La première lecture de ton message a été rapide de ma part ... mais la après réflexion, l'erreur générée est à cause du fait que tu veuille créer un datarow à partir de son contructeur ....
    je m'explique, Quand tu fais un code du genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    IEnumerable<DataRow> resultat=...
                                                          Select new 
                                                          {
                                                             ......
                                                          }
    en interne le result du select est un type anonyme qui va être converti en une énumération de DataRow. D'OÙ LE PROBLÈME. Car pour la conversion le compilateur doit passer par le constructeur de DataRow. Étant donné que ce dernier n'est pas accessible en public donc l'exception est générée ....
    J'espère que c'est plus clair ... et dsl pour mon absence d'esprit lors de la lecture de ton message ...


    (Si je peux me permettre, dans quel but veux tu utiliser le linq ? je pourrais peut être donner des idées...)

    Bon courage

  7. #7
    Membre du Club
    Inscrit en
    Mai 2006
    Messages
    98
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 98
    Points : 53
    Points
    53
    Par défaut
    Pas grave Buxus, merci pour ton aide

    Je veux utiliser Linq pour permettre à mes utilisateurs filtrer le résultat d'une requête sql (ou le contenu d'une table d'ailleurs, soyons pas sectaires) de façon rapide (genre une case ou plusieurs cases à cocher) et linq me permet de le faire sans avoir à interagir avec le serveur donc à priori, ça va plus vite

    En tous cas pour le moment, je m'en sors sans avoir à besoin de créer de classe anonyme donc ça devrait le faire (et à priori je pense pas en avoir besoin \o/ j'espère juste que je me trompe pas)

  8. #8
    Inactif
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    59
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : Algérie

    Informations forums :
    Inscription : Juillet 2009
    Messages : 59
    Points : 73
    Points
    73
    Par défaut dommage
    Et bien Dommage Yal ...
    Linq est un outil très puissant ... Pour tout te dire j'en suis devenu acro. Depuis peu toutes les class library (dll) que je fais pour l'équipe (ou presque toutes) qui touchent les données utilisent le linq ... car même si t'arrive à une certaine limite imposée par de contraintes il y a toujours la reflection qui te sauve la face ... et puis apprendre le linq est la meilleur façon de booster tes connaissance dans d'autres volets comme les ORM (genre XPO ou Nhibernate). alors n'hésites pas à persister et si je peux aider ça sera avec plaisir ...
    En ce qui concerne ton problème le linq va beaucoup t'aider et te faciliter la maintenance de ton code ... même si cette solution ne t'arrange pas trop tu peux toujours créer une boucle foreach et créer ta DataTable ...

    enfin ravi d'en avoir discuté ...
    bon courage

  9. #9
    Membre du Club
    Inscrit en
    Mai 2006
    Messages
    98
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 98
    Points : 53
    Points
    53
    Par défaut
    Ce que je voulais dire, c'est que je n'ai pas besoin de créer de classe anonyme, je compte bien me servir de Linq

  10. #10
    Membre du Club
    Inscrit en
    Mai 2006
    Messages
    98
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 98
    Points : 53
    Points
    53
    Par défaut
    Un lien qui résout mon problème, je recommande

    http://msdn.microsoft.com/fr-fr/library/bb669096.aspx

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réutiliser des données d'une requête dans une requête
    Par mims1664 dans le forum Requêtes
    Réponses: 12
    Dernier message: 06/02/2009, 14h12
  2. Résultat d'un champ d'une requête dans une variable
    Par PsychedeChed dans le forum Requêtes et SQL.
    Réponses: 2
    Dernier message: 11/01/2009, 12h50
  3. Réponses: 4
    Dernier message: 02/07/2008, 11h32
  4. Réponses: 2
    Dernier message: 02/06/2006, 11h26
  5. Réponses: 4
    Dernier message: 01/12/2005, 14h36

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