mercredi 12 mars 2008

Entity Framework et les fonctions SQL

Voulant utiliser une fonction scalaire SQL avec Entity Framework, je me suis heurté à quelques difficultés techniques. Il a fallu chercher la réponse du côté d'Entity SQL et de la couche logique du modèle d'Entity Framework (lire l'article de john Papa pour comprendre les couches d'Entity FrameWork).

Distinguons d'abord les fonctions canoniques des fonctions utilisateurs.
Pour les premières pas trop de soucis d'utilisation (lire la note de Zlatko Michailov), exemple:

MonObjetContext.CreateQuery("select value r from [MaTable] as r where Length('abc')=3;").ToList();
Par contre, pour les fonctions utilisateurs, ce n'est plus si simple (cf. mon post sur le forum que je résume ici). Je remplace la fonction canonique Length par une fonction utilisateur MaFonction.
Le même code lève une erreur à l'execution:

MonObjetContext.CreateQuery("select value r from [MaTable] as r where MaFonction('abc')=3;").ToList();
Pour que ça s'execute bien, EntitySQL doit savoir ou rechercher la définition de cette fonction. La définition va se trouver dans la couche logique de mon modèle (celle qui mappe ma base de données), c'est à dire dans le SSDL (que l'on trouve sous bin\ObjectContext ou directement dans la vue xml de MonEDM.edmx). En regardant de plus prêt dans le fichier MonEDM.ssdl, on trouve le nom du namespace et la définition de la fonction:

<schema xmlns="http://schemas.microsoft.com/ado/2006/04/edm/ssdl" namespace="MonEDM.Store" alias="Self" providermanifesttoken="09.00.1399">

<function name="MaFonction" returntype="int" aggregate="false" builtin="false" niladicfunction="false" iscomposable="true" parametertypesemantics="AllowImplicitConversion" schema="dbo">
Avec ces informations, je peux maintenant appeler ma fonction via EntitySQL en spécifiant le namespace:
MonObjetContext.CreateQuery("using MonEDM.Store;select value r from [MaTable] as r where MaFonction('abc')=3;").ToList();
sans erreur d'execution.

Aucun commentaire:


Laurent Morisseau, auteur de ce blog, pour me contacter