Wilfried Woivré & .Net

Entity Framework 4 : Générer des scripts Sql

SEPT16

/* Ce post a été écrit avec la version Visual Studio 2010 Beta et la CTP1 d’Entity Framework, il se peut donc qu’il ne soit plus valable lorsque vous le lirez */

Dans la version actuelle du Framework, soit la 3.5 SP1, Microsoft nous a offert Entity Framework qui est certes très puissants, mais tout de même incomplet au niveau de certaines fonctionnalités. Bien entendu, je pense à la création du script Sql ou de la base de données associée au schéma que nous avons créé. Heureusement la version 4 approchant à grand pas, avec son lot de fonctionnalité pour nous faciliter la vie, surtout sur ce point de vue.

 

Avant tout vous pouvez télécharger la version de EF4 CTP1 à cette adresse : http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=7fd7164e-9e73-43f7-90ab-5b2bf2577ac9

Et il vous faudra bien entendu Visual Studio 2010 Beta et un Sql Serveur 2008 pour que cette fonctionnalité puisse fonctionner correctement. N’oublions pas que c’est une CTP, nous n’avons qu’à espérer qu’il supporte aussi les anciennes versions de Sql (2000 & 2005)

Alors commençons par créer une application console afin d’effectuer cette démonstration, puis rajoutons notre fichier edmx en utilisant un modèle vide. Nous avons donc le designer de notre fichier vierge, ou nous pouvons ajouter les éléments que l’on souhaite. On va donc créer ici nos différents objets que l’on se servira dans notre application.

Alors prenons un modèle assez simple tel que celui ci :

image

On peut donc voir une relation n-aire entre des employés et leur entreprise, de plus on voit ici l’apparition du champ Adresse qui est un type complexe que j’ai crée comme on peut le voir dans ces propriétés :

image

Ce champ complexe contient divers autres champs. Cette possibilité aussi arrivé avec EF4 vous permettra d’extraire différents champs communs à vos tables afin de créer un objet associés à ceux ci sans pour autant à avoir à créer une table pour ceux ci. Comme typiquement ce champ adresse qui peut se retrouver aussi bien chez un contact, un employé, une entreprise, un fournisseur et qui pourtant n’a aucun lieu dans le modèle à être séparé de ces tables. image

Maintenant que nous nous sommes crée notre schéma qui va bien, que nous avons modifié certaines propriétés de notre modèle, tel que par exemple notre Entity Set Name, nous pouvons passer à la génération du script. Donc comme je l’aime bien dans Visual Studio, cette opération se trouve fortement complexe, et n’est pas disponible à ceux qui ne fouillent pas dans l’application. Mais sinon faites un clic droit et “Generate Database Script from Model …”

 

image

Donc après vous avoir choisi votre base de données, il vous génère votre fichier sql , il ne vous reste plus qu’à l’exécuter et vérifier le résultat :

image

On voit donc bien nos deux tables avec notre type complexe inclus à l’intérieur de chacune d’elle.

 

Alors pour conclure, on peut dire que cette possibilité de génération était une chose tant attendu à Entity Framework, puisque effectivement ça manquait encore à sa panoplie de compétence. Mais ceci est réglé à présent ! De plus, cela peut permettre de construire des bases de données avec une notion beaucoup plus objets grâce aux types complexes ! Cette nouvelle mouture d’Entity Framework correspond bien à l’ancienne, innovante, pratique, et bientôt indispensable pour toutes les applications.

Remonter

Silverlight et l’accès aux bases de données

FÉVR4

Lors de la création d'un projet, il y a toujours une question qui revient c'est celle sur l'accès aux données.

En effet comment accède-t-on aux données depuis une application aujourd'hui ?

  • Un accès direct à la base de données
  • Un Web Service
  • WCF et ses différents types de binding

Mais pour ce qui est de Silverlight, il est évident qu'on ne peut pas utiliser tous ces types d'accès, en effet on a jamais vu une application cliente se connecter directement à une base de données.

De plus, à quelle base de données peut-on se connecter, car j'espère que tout le monde qui lis ce post sait qu'on peut ajouter des modules Silverlight aussi bien dans une page aspx (ASP.Net) qu'une bonne page html.

Alors personnellement, j'ai utilisé des méthodes aussi libre que propriétaire. C'est à dire une base de données MySQL, un accès direct aux données via diverses pages en php qui génèrent des données XML récupérées dans mon application Silverlight via l'accès aux pages php en question. Où une solution plus propriétaires, soit Sql Serveur 2008, un accès aux données avec Linq To Sql, et un service WCF pour diffuser les données.

Donc je me suis dis une petite démo pour les deux méthodes, histoire que vous puissiez tous profiter de ces exemples pour vos futures applications. De plus, vous pourrez trouver à la fin de ce post un lien pour télécharger les différentes sources utilisé pour la création de cet article.

Commençons par la solution gratuite, c'est à dire MySQL + PHP + Silverlight avec un petit schéma pour une compréhension plus facile.

Alors il faut penser à l'accès aux données et aux envois des nouvelles données à notre base.

Donc pour l'accès à la base en PHP, je vais supposer que tout le monde sait faire (enfin si vous ne savez pas, ce n'est pas grave vous n'allez pas en mourir). Mais en gros il faut créer un XML pour qu'on puisse le lire à travers notre application Silverlight

while ($line = mysql_fetch_assoc($result))
{
echo "<Favori>";
$id = $line["Id"];
echo "<id>".$id."</id>";
echo "<Lien>".utf8_encode($line["Lien"])."</Lien>";
echo "<Libelle>".utf8_encode($line["Libelle"])."</Libelle>";
echo "<Auteur>".utf8_encode($line["Auteur"])."</Auteur>";
echo "</Favori>";
}

Vous obtenez grâce à cette boucle une syntaxe XML de ce type, pour une entité Favori :

<Favori>

<id>1</id>

<Lien>http://etudiants.ms</Lien>

<Libelle>Site Microsoft étudiants</Libelle>

<Auteur>Microsoft</Auteur>

</Favori>

Maintenant viens la récupération de ce code XML au travers de l'application Silverlight, j'utilise donc un Helper pour récupérer ces valeurs via un WebClient, puis je traite les données récupérées via un LinqToXML, et ensuite les utiliser à bon escients dans mon application.

Pour la récupération en LinqToXML, j'ai utilisé une requête assez simple que voici :

var elements = xmlElements.Descendants("Favori").Select(favori => new

{

Id = (int)favori.Element("id"),

Auteur = ((string)favori.Element("Auteur")).Trim(),

Libelle = ((string)favori.Element("Libelle")).Trim(),

Lien = ((string)favori.Element("Lien")).Trim()

});

Voilà pour la récupération des données avec cette méthode, et maintenant voyons comment envoyé des données au serveur, car après tout un échange se fait dans les deux sens.

Alors pour l'envoi des données, j'ai aussi utilisé un Helper pour envoyer les données.


HttpHelper helper = new HttpHelper(new Uri("http://myWebSite/setFavori.php"), "POST"

, new KeyValuePair<string, string>("Favori", null)

, new KeyValuePair<string, string>("Favori_Libelle", "Imagine Cup Student Competition 2009")

, new KeyValuePair<string, string>("Favori_Lien", " http://imaginecup.com")

, new KeyValuePair<string, string>("Favori_Auteur", "Microsoft"));

helper.ResponseComplete += new HttpResponseCompleteEventHandler(helper_ResponseComplete);

helper.Execute();

En fait le but de ce helper est d'ajouter les données dans différentes données à poster selon le type de méthode voulue, ici en mode « POST », pour plus de détails voici le constructeur utilisé ci-dessus.


public HttpHelper(Uri requestUri, string method, params KeyValuePair<string, string>[] postV alues)

{

Request = (HttpWebRequest)WebRequest.Create(requestUri);

Request.ContentType = "application/x-www-form-urlencoded";

Request.Method = method;

PostValues = new Dictionary<string, string>();


if (postValues != null && postValues.Length > 0)

{


foreach (var item in postValues)

{

PostValues.Add(item.Key, item.Value);

}

}

}

On récupère ensuite ces différentes données via le fichier setFavori.php, puis on les ajoute à la base de données MySQL via un code de ce type, on remarquera par ailleurs que mon niveau en PHP n'est pas très élevé.

if (isset($_POST["Favori"]))

{

$Libelle = mysql_real_escape_string($_POST["Favori_Libelle"]);

$Lien = mysql_real_escape_string($_POST["Favori_Lien"]);

$Auteur = mysql_real_escape_string($_POST["Favori_Auteur"]);

$query = "INSERT INTO `Flux` (`Id`, `Libelle`, `Lien`, `Auteur`) VALUES (NULL, '".$Libelle."', '".$Lien."', '".$Auteur."')";

$result = mysql_query($query);

if(!result)

echo "ERR2";

}

On effectue donc l'ajout en base, et on écrit un code d'erreur qui sera lu par l'application Silverlight afin d'informer l'utilisateur d'un éventuel souci.

Passons maintenant à la partie « Full Microsoft », une solution où d'ailleurs je me sens plus à l'aise, peut-être du au fait que j'ai rarement fait du PHP durant ma carrière de développeur. Donc pour commencer un petit schéma du fonctionnement de l'exemple.

Donc avant tout un LinqToSql, dont voici le fichier dbml qui est comme vous pouvez le voir assez succinct.

Et oui, encore l'exemple du favoris, on remarque que cela change de l'exemple de la personne J

On construit ensuite le WCF, je vais passer sur la création d'un service WCF puisque ce n'est pas le but de cet article, mais néanmoins voici les différentes méthodes exposées sur le Web Services.


///<summary>

/// Récupère la liste des favoris de la base

///</summary>

///<returns></returns>
List<WCF_DataContract.Favori> WCF_Interface.IService.SelectAllFavoris()

{
if (db != null && db.DatabaseExists())

{
var query = from f in db.Favoris

select new WCF_DataContract.Favori

{

Id = f.IdFavori,

Libelle = f.Libelle,

Auteur = f.Auteur,

Lien = new Uri(f.Lien)

};


return query.ToList();

}

< span="" style="font-family:courier new;font-size:10pt;">
return null;

}


///<summary>

/// Insère un favori dans la base et retourne son id

///</summary>

///<param name="obj"></param>

///<returns></returns>
void WCF_Interface.IService.insertFavori(WCF_DataContract.Favori obj)

{


if (db != null && db.DatabaseExists())

{


Favori f = new Favori()

{

Lien = obj.Lien.AbsoluteUri,

Auteur = obj.Auteur,

Libelle = obj.Libelle

};

db.Favoris.InsertOnSubmit(f);

db.SubmitChanges();

}

}

Donc on peut voir ci-dessous, la méthode pour insérer et pour récupérer tous les éléments de la liste.

Pour publier notre service WCF dans notre site web, rien de plus, il faut configurer le fichier de configuration correctement, et créer un fichier « .svc » après bien entendu avoir ajouter toutes les références nécessaire.

Voici les données du fichier de configuration :

<system.serviceModel>

<services>

<service name="WCF_Services.Service" behaviorConfiguration="MyServiceTypeBehaviors">

<endpoint address="" binding="basicHttpBinding" contract="WCF_Interface.IService" />

</service>

</services>

<behaviors>

<serviceBehaviors>

<behavior name="MyServiceTypeBehaviors">

<serviceMetadata httpGetEnabled="true" />

</behavior>

</serviceBehaviors>

</behaviors>

</system.serviceModel>

Et le contenu du fichier « .svc » : <%@ ServiceHost Service="WCF_Services.Service" %>

Bien entendu, l'implémen tation d'un service WCF peut être bien plus compliquée selon les besoins du projet.

Passons au projet Silverlight, on ajoute une référence à notre service WCF précédemment crée, comme le montre l'écran ci-dessous.

Pour la récupération de tous les favoris, on utilise donc ces différentes méthodes :


private ServiceClient client;


public void Load()

{

client = new ServiceClient();

client.SelectAllFavorisCompleted += new EventHandler<SelectAllFavorisCompletedEventArgs>(client_SelectAllFavorisCompleted);

client.SelectAllFavorisAsync();

}


void client_SelectAllFavorisCompleted(object sender, SelectAllFavorisCompletedEventArgs e)

{
var MyList = e.Result.ToList();

client.CloseAsync();

}

La variable MyList contient dorénavant toutes les données de la base.

Note : Il ne faut pas oublier de fermer la connexion avec le service WCF afin de libérer les ressources, pour qu'elles soient nettoyés par le Garbage Collector.

Donc voici, comme promis les sources de la solution sur ce lien.

Alors pour conclure ce post, on peut dire que voici deux solutions diverses pour accéder à des bases de données depuis Silverlight, on peut bien entendu envisager à partir de ces exemples toutes les possibilités immaginables et réalisables ce qui ne rendra pas vos applications Silverlight isolée sur le poste de l'utilisateur final.

Wilfried Woivré

Remonter