10juil. 2009

CSharp 3 : Requête OUTER JOIN avec Entity et Linq

J'ai récement eu une jointure externe à faire avec le framework entity associé à Linq.

Première déconvenue, il n'y a pas en Linq de mot clé "outer". Autant le dire tout de suite : faire une jointure externe sur des objets entity ne sera pas simple.

DefaultIfEmpty() ... ou pas ?

Il est possible - mais je ne l'ai pas mis en oeuvre - d'utiliser des groupe join avec la méthode DefaultIfEmpty() qui permet d'avoir des null lorsqu'il n'y pas d'équivalence. Cette méthode n'est pas (encore ?) implémentée sur les objets Entity.

Voici un exemple tiré du site Solid Coding :

var query = (from p in dc.GetTable<Person>()
        join pa in 
            dc.GetTable<PersonAddress>() 
        on p.Id equals pa.PersonId 
        into tempAddresses
        from addresses 
            in tempAddresses.DefaultIfEmpty()
    select new { p.FirstName, p.LastName, 
        addresses.State });

La méthode DefaultIfEmpty() quand elle est implémentée permet d'obtenir une valeur lorsqu'il n'y a pas de correspondance.

Une solution serait de définir cette méthode avec une surcouche héritant des objets Entity.

L'alternative que j'ai choisi et d'utiliser du Entity SQL. A savoir qu'il est possible d'écrire des requêtes ressemblant à du SQL pour interroger un modèle Entity.

Entity SQL : Là où Linq s'arrête

En utilisant du eSQL, il est possible d'utiliser des mots clés SQL pour récupérer des données à partir du model Entity. L'eSQL ne peut être considéré comme du SQL pur.

La requête stockée dans une chaine de caractère est traduite en TSQL avant d'être transmise au serveur. Ce qui peut parfois donner des choses originale (surabondance de clause EXISTS etc ...). Attention au performance donc.

Sources