Dot.Blog

C#, XAML, WinUI, WPF, Android, MAUI, IoT, IA, ChatGPT, Prompt Engineering

Un outil gratuit pour tester les requêtes LINQ

Qu'il s'agisse de LINQ to Object ou LINQ to SQL il serait bien agréable de pouvoir disposer d'une sorte de bloc-note pour tester ou mettre au point des requêtes, voire pour s'entraîner tout simplement. Pouvoir gérer les connexions aux bases de données, éventuellement envoyer et tester du SQL "de base" sur celles-ci serait la cerise sur la gâteau. Et bien cet outil existe, et en plus il est gratuit !

 

LINQPad, puisque c'est de lui qu'il s'agit, n'est pas vraiment une nouveauté absolue mais il y a fort à parier que nombre d'entre vous n'en ont jamais entendu parlé.

Cet outil a été développé conjointement à l'excellent ouvrage "C# 3.0 in a nutshell" de Joseph Albahari, un australien, qui par la diffusion gratuite de LINQPad tente une promo plutôt positive de son livre et de ses services de consulting (si on habite au pays des kangourous, of course).

J'aime personnellement cette idée de "pub positive" qui consiste à offrir de son temps et de son travail pour faire sa pub plutôt que de gaver les gens de bandeaux agaçants. C'est de la pub dans un esprit totalement anti-google (de la pub pour de la pub, partout, sans rien apporter à ceux qui la subissent), et il faut encourager ceux qui adoptent cette façon respectueuse de faire leur promotion. Achetez le livre de Joseph ! Fin de la paranthèse :-)

LINQPad est ainsi un super utilitaire. Il interprète du code C# ou VB et les requêtes LINQ to Object ou LINQ to SQL. Il autorise la connexion à des bases de données, offre un éditeur purement SQL en supplément, bien pratique, et il permet même d'ajouter ses propres DLL et ses propres espaces de noms pour qu'ils soient reconnus dans le code C# qu'on tape !

On peut dès lors utiliser LINQPad pour requêter des objets métiers complexes, un framework maison, un modèle LINQ to SQL, etc.. Il suffit d'ajouter les références.

Pour terminer, LINQPad est fourni avec de nombreux exemples qui sont autant de moyens de tester ses connaissances et d'apprendre les subtilités de LINQ. Utilisé conjointement à ma version des "101 exemples LINQ" de Microsoft, LINQPad devient un fantastique outil d'auto-formation.

Pour télécharger le produit et avoir accès aussi aux forums, aux vidéos de démo, et plein d'autres choses, aller sur la page de LINQPad !

Bon Dev...

Et Stay Tuned !

 

Mettre des données en forme en une requête LINQ

Losqu'on traite de LINQ, la majorité des exemples utilisent des sources de données "bien formées" : flux RSS (mon dernier billet), collections d'objets, etc. Mais dans la "vraie vie" les sources de données à traiter sont parfois moins "lisses", moins bien formées. LINQ peut aussi apporter son aide dans de tels cas pour transformer des données brutes en collection d'objets ayant un sens. C'est ce que nous allons voir dans ce billet.

Prenons un exemple simple : imaginons que nous récupérons une liste de rendez-vous depuis une autre application, cette liste est constituée de champs qui se suivent, les initiales de la personne, son nom et l'heure du rendez-vous. Tous les rendez-vous se suivent en une longue liste de ces trois champs mais sans aucune notion de groupe ou d'objet.

Pour simplifier l'exemple, fixons une telle liste de rendez-vous dans un tableau de chaînes :

string[] data = new[] { "OD", "Dahan", "18:00", "MF", "Furuta", "12:00", "BG", "Gates", "10:00" };

La question est alors comment extraire de cette liste "linéaire" les trois objets représentant les rendez-vous ?

La réponse passe par trois astuces :

  • L'utilisation de la méthode Select de LINQ qui sait retourner l'index de l'entité traitée
  • La syntaxe très souple de LINQ permettant d'utiliser des expressions LINQ dans les valeurs retournées
  • Et bien entendu la possibilité de créer des types anonymes

Ce qui donne la requête suivante :

var personnes = data.Select ( (s, i) => new
                                          {
                                             Value = s,
                                             Bloc = i / 3
                                          }
                                        ).GroupBy(x => x.Bloc)
                                        .Select ( g => new 
                                                    {
                                                      Initiales = g.First().Value,
                                                      Nom = g.Skip(1).First().Value,
                                                      RendezVous = g.Skip(2).First().Value
                                                     } );

L'énumération suivante : 

foreach (var p in personnes.OrderBy(p=>p.Nom)) Console.WriteLine(p);

donnera alors cette sortie console de toutes les personnes ayant un rendez-vous, classées par ordre alphabétique de leur nom :

{ Initiales = OD, Nom = Dahan, RendezVous = 18:00 }
{ Initiales = MF, Nom = Furuta, RendezVous = 12:00 }
{ Initiales = BG, Nom = Gates, RendezVous = 10:00 }

Voici des objets bien formés (on pourrait ajouter un DateTime.Parse à la création du champ RendezVous pour récupérer une heure plutôt qu'une chaîne) qui pourront être utilisés pour des traitements, des affichages, une exportation, etc...

LINQ to Object ajoute une telle puissance à C# que savoir s'en servir au quotidien pour résoudre tous les petits problèmes de développement qui se posent permet réellement d'augmenter la productivité, ce que tous les langages et IDE promettent falacieusement (aucune mesure de ce supposé gain n'existe). Ici, essayez d'écrire le même code sans LINQ, vous verrez tout suite que le gain de productivité et de fiabilité est bien réel, et que la maintenance aura forcément un coup moindre.

Pour d'autres infos, Stay Tuned !

Le projet VS 2008 : LinqChunk.zip (5,35 kb)

Traiter un flux RSS en 2 lignes ou "les trésors cachés de .NET 3.5"

.NET 3.5 apporte beaucoup de classes nouvelles et d'améliorations à l'existant. Certains ajouts sont plus médiatisés que d'autres. Mais il serait injuste de limiter cette mouture à LINQ ou aux arbres d'expressions, aussi géniales et puissantes soient ces avancées.

.NET 3.5 apporte réellement une foule de nouveautés parmi lesquelles il faut noter :

  • L'apport de WCF et de LINQ au compact framework
  • De nouvelles facilités pour contrôler le Garbarge Collector comme le LatencyMode de la classe GCSettings
  • L'ajout de l'assemblage System.NetPeerToPeer.Collaboration qui permet d'utiliser les infrastructures de peer-to-peer
  • Des améliorations importantes de WCF, l'intégration WCF-WF
  • etc...

Pour une liste complète des nouveautés il est intéressant de jeter un oeil à cette page MSDN.

Un exemple qui illustre les avancées plus ou moins méconnues de .NET 3.5, l'espace de noms System.ServiceModel.Syndication dans la dll System.ServiceModel.Web apporte de nouvelles facilités pour gérer des flux RSS. Et pour s'en convaincre quelques lignes de codes :

SyndicationFeed feed;
using (var r = XmlReader.Create(https://www.e-naxos.com/Blog/syndication.axd))
{ feed = SyndicationFeed.Load(r); }

C'est tout ! Dans la variable "feed" on a tout ce qu'il faut pour travailler sur le flux RSS.

Vous pensez que je triche et que "travailler sur le flux RSS" c'est certainement pas si simple que ça ?. Bon, allez, c'est parce que c'est vous : compliquons même la chose et, à partir de ce flux, affichons le titre de tous les billets qui parlent de LINQ dans leur corps. Voici le code complet près à compiler :

using System;
using System.Linq;
using System.ServiceModel.Syndication;
using System.Xml;

namespace NET35RSS
{ class Program
  {
     static void Main()
     {
        SyndicationFeed feed;
        using (var r = XmlReader.Create(
https://www.e-naxos.com/Blog/syndication.axd))
        { feed = SyndicationFeed.Load(r); }
           if (feed==null) { Console.WriteLine("Flux vide."); return; }
           Console.WriteLine(feed.Title.Text);
           Console.WriteLine(feed.Description.Text+"\n");
           var q = from item in feed.Items
           where item.Summary.Text.ToUpper().Contains("LINQ") select item;
           foreach (var item in q) Console.WriteLine(item.Title.Text);
       }
    }
}

Ajoutez une petite saisie pour le mot à chercher au lieu d'un codage en dur ("LINQ" dans cet exemple) et un petit fichier paramètre pour y stocker la liste des blogs que vous connaissez, et en deux minutes vous aurez un puissant outil de recherche capable de vous lister toutes les billets de vos blogs préférés qui parlent de tel ou tel sujet...

C'est pas génial ça ?

Si, ça l'est, bien sûr ! Alors Stay Tuned !

pour les paresseux du clavier, le projet VS 2008 : NET35RSS.zip (5,36 kb)

LINQ et Réflexion pour obtenir les valeurs de System.Drawing.Color

LINQ... l'un de mes sujets préférés... Plus je l'utilise, à toutes les sauces, et plus je trouve cette technologie indispensable. Mais foin de propagande, voici encore un exemple qui prouve à quel point LINQ peut servir à tout, facilement.

Le but du jeu : récupérer la définition des couleurs de System.Drawing.Color, en faire un tableau trié par ordre alphabétique.

A la "main" je vous souhaite bien du plaisir... Avec LINQ cela donne la chose suivante :

namespace LinqColor
{
  class Program
  {
     static void Main(string[] args)
    {
       var color_type = typeof(System.Drawing.Color);
       var color_properties = from prop in color_type.GetProperties()
                                     where prop.PropertyType == color_type
                                     orderby prop.Name
                                     select prop;
       
       foreach (var color_property in color_properties)
       {
           var cur_color = (System.Drawing.Color) color_property.GetValue(null, null);
           uint rgb_int = (uint) cur_color.ToArgb() & (0x00ffffff);
           Console.WriteLine(" {0,-20} = ({1,-3},{2,-3},{3,-3}) = 0x{4:X00000000}",
           color_property.Name,
           cur_color.R, cur_color.G, cur_color.B,rgb_int);
       }
    }
  }
}

La sortie écran (console) donne la chose suivante :

Le projet VS 2008 pour les fénéants du clavier : LinqColor.zip (5,43 kb)

C'est pas merveilleux LINQ ?

Bien sûr que si... Alors Stay Tuned !

La bombe Parallèle ! PLINQ, et PCP Parallel Computing Platform

Le framework .NET n'en finit pas d'innover ! La bombe du jour c'est PLINQ et PCP.

Vous ne connaissez pas encore ? Normal, ce n'est même pas encore sorti, juste en preview...

Pour résumer en un mot : Révolutionnaire. Comme LINQ.

L'objectif

Vous l'avez certainement remarqué comme tout geek qui se respecte, depuis quelques années nos amis fondeurs ne se battent plus à coup de Ghz pour promouvoir leurs microprocesseurs... Les gammes se multiplient et surtout les coeurs ! Et le temps où le concepteur d'un soft trop lent pouvait toujours dire "je suis en avance c'est tout, avec la dernière génération de processeur mon soft est super rapide!", ce temps là est fini, révolu.

Aujourd'hui un soft lent sur un dual core sera peut être même encore plus lent sur un quad core d'une autre série (il y a plein de séries de processeurs on ne s'y retrouve d'ailleurs plus pour choisir...).

Donc, pour qu'un soft soit plus rapide, inutile de compter sur la prochaine génération de processeur qui doublera la fréquence d'horloge. Aujourd'hui on double le nombre de coeurs, c'est tout. un, puis deux, les quatre coeurs se banalisent, Intel avait annoncé (le tiendront ils) que d'ici peu de temps on atteindrait les 100 coeurs... Mais pour tirer partie de tous ces coeurs finalement pas si rapide, une seule solution le parallélisme !

Parallèlisme et programmation

Seulement voilà, pour bénéficier de tous ces coeurs il faut programmer selon un mode parallèle. Le plus "simple" consiste à faire du multi-threading en laissant l'OS répartir les threads entre les coeurs, mais pour plein de raison (je vous laisse y réfléchir) cela n'est pas forcément optimal. Un simple exemple : une tâche un peu lourde, vous n'avez pas besoin de 50 threads, vous avez une grosse bonne boucle qui traite une image pour faire du morphing par exemple. Allez programmez ça en créant plusieurs threads ! Si vous y arriver sans y engloutir des semaines de mise au point, je veux bien manger mon chapeau (il faudra fournir le chapeau je n'en porte pas, et si vous le fournissez, ça ne sera pas le mien, donc je ne le mangerais pas. On ne m'a pas si facilement...) !

Car en effet, multiplier les threads n'est pas toujours réalisable, en tout cas simplement. Découper une tâche en sous tâches parallélisables est en réalité tellement complexe, surtout de façon générique, que les langages et les OS sont bien à la traîne par rapport aux microprocesseurs. A la traîne ? Pas tous... Car sous .NET il va falloir compter avec PLINQ et PCP !

PLINQ et PCP

En très gros il s'agit d'extensions du framework .NET qui permet de paralléliser à peu près tout traitement sans presque aucune programmation particulière. Oui vous avez bien lu...

Ainsi, PLINQ est une extension parallèle de LINQ. Une requête LINQ comme :

var result = from c in liste where c.champ==5 orderby c.autreChamp select c; // version simple

devient en parallèle :

var result = from c in liste.AsParallel() where c.champ==5 orderby c.autreChamp select c; // parallélisée

Et c'est tout ! D'un seul coup la requête devient parallèle et s'executera sur tous les coeurs disponibles à la fois, le boulot étant découpé, les threads créés, et tout le reste, de façon automatique par PLINQ. Un rêve ? Non, pas besoin de se pincer, c'est déjà en preview à télécharger ! (voir en fin de billet).

Bien entendu il existe beaucoup de variantes et une syntaxe appropriée pour, par exemple, modifier le nombre de coeurs utilisés et plein d'autres nuances subtiles.

La parallélisation de LINQ est une pure merveille, mais il y a aussi PCP qui est le framework plus généraliste permettant de paralléliser des foreach, des for, etc, juste avec un mot clé. Il existe là aussi toute une panoplie de méthodes qu'il va falloir découvrir. Mais vous avouerez que le bond en avant est aussi fantastique que celui de LINQ par exemple. Je ne pense sincèrement pas que quiconque ayant utilisé LINQ ne voudra dans l'avenir d'un langage ne supportant pas une telle extension. Il y a eu un avant LINQ, il y aura forcément un après LINQ, mais on ne traversa pas le temps sans faire référence à cette nouvelle ère, au sens premier, le clou d'airain planté par le prêtre dans la mur du temple de la Rome antique pour marquer un événement crucial d'une telle importance qu'une nouvelle série d'années commençait.

PLINQ et PCP marqueront de la même façon une nouvelle ère.

Faire joujou ?

Je reconnais bien le geek qui sommeille en vous ! Oui c'est possible ! Il existe une CTP sortie en juin et qui est téléchargeable sur le site MSDN consacré à la programmation parallèle. Vous y trouverez de nombreuses informations qui complèteront facilement la très rapide présentation faite ici.

Le site : http://msdn.microsoft.com/fr-fr/concurrency/

... Vous êtes encore là ? Mais foncez je vous dit, c'est l'éclate du geek ce truc ! (mais pensez à revenir hein.. Stay Tuned !) Wink

[EDIT: lire aussi ce billet plus récent qui donne l'adresse d'un article sur PFX et de plusieurs Webcasts]