157 votes

Remplir un DataSet ou un DataTable à partir d'un ensemble de résultats d'une requête LINQ

Comment exposer une requête LINQ en tant que service web ASMX ?
Habituellement, à partir du niveau de l'entreprise, je peux renvoyer un fichier de type DataSet ou un DataTable qui peuvent être sérialisées pour être transportées sur ASMX.

Comment puis-je faire de même pour une requête LINQ ?
Existe-t-il un moyen de remplir un formulaire de type DataSet ou un DataTable via une requête LINQ ?

public static MyDataTable CallMySproc()
{
    string conn = "...";

    MyDatabaseDataContext db = new MyDatabaseDataContext(conn);
    MyDataTable dt = new MyDataTable();

    // execute a sproc via LINQ
    var query = from dr
                in db.MySproc().AsEnumerable
                select dr;

    // copy LINQ query resultset into a DataTable -this does not work !    
    dt = query.CopyToDataTable();

    return dt;
}

Comment puis-je placer le jeu de résultats d'une requête LINQ dans un fichier de type DataSet ou un DataTable ?
Sinon, la requête LINQ peut-elle être sérialisée afin que je puisse l'exposer comme un service web ASMX ?

98voto

Jon Galloway Points 28243

Comme mentionné dans la question, IEnumerable a un CopyToDataTable méthode :

IEnumerable<DataRow> query =
    from order in orders.AsEnumerable()
    where order.Field<DateTime>("OrderDate") > new DateTime(2001, 8, 1)
    select order;

// Create a table from the query.
DataTable boundTable = query.CopyToDataTable<DataRow>();

Pourquoi ça ne marche pas pour toi ?

30 votes

A tous ceux qui se demandent pourquoi CopyToDataTable() ne fonctionne pas sur leur machine : Cette fonction ne fait pas partie de .NET 3.5 SP1 et ne fera pas partie de .NET 4.0 ; elle a été restreinte à IEnumerable<DataRows> et ne fonctionne pas pour IEnumerable<T> --. bit.ly/dL0G5

32voto

Pour exécuter cette requête contre un DataContext vous devez effectuer les opérations suivantes :

MyDataContext db = new MyDataContext();
IEnumerable<DataRow> query = 
    (from order in db.Orders.AsEnumerable()
        select new
        {
            order.Property,
            order.Property2
        })
    as IEnumerable<DataRow>;
return query.CopyToDataTable<DataRow>();

Sans le as IEnumerable<DataRow>; vous verrez l'erreur de compilation suivante :

Impossible de convertir implicitement le type 'System.Collections.Generic.IEnumerable' en 'System.Collections.Generic.IEnumerable'. Une conversion explicite existe (il vous manque un cast ?)

24voto

Lars Mæhlum Points 4569

Créer un ensemble d'objets de transfert de données, un couple de mappeurs, et renvoyer le tout via le .asmx.
Vous devez nunca exposer directement les objets de la base de données, car une modification du schéma de la procédure se propagera au consommateur du service web sans que vous vous en rendiez compte.

18voto

Dave Ward Points 36006

Si vous utilisez un type de retour de IEnumerable vous pouvez retourner votre requête variable directement.

14voto

Brian Childress Points 437

Créer un objet de classe et retourner un list(T) de la requête.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X