Traduction▲
Cet article est la traduction la plus fidèle possible de l'article original de Brad Abrams, Business Apps Example for Silverlight 3 RTM and .NET RIA Services July Update: Part 17: Evolving an application.
Article▲
Voilà encore des choses tirées de ma présentation du Mix09 « Building business applications with Silverlight 3 ». Jusqu'ici, dans cette série, nous avons vu comment créer une nouvelle application en utilisant Silverlight 3 et .NET RIA Services. Mais voyons maintenant comment faire évoluer une application SL3/RIA Services existante. Après tout, pour la plupart d'entre nous, c'est notre travail quotidien. Il est rare d'avoir l'occasion de commencer à partir de rien une application sur laquelle on a tout contrôle. La possibilité de gérer la maintenance d'une application permet à un framework de passer du statut de « super jouet de démo » à celui d'outil important.
Pour le contexte, vous pouvez regarder la vidéo originale de la session complète, et lire le reste de la série.
Cette démo nécessite les éléments suivants (tout est 100 % gratuit) :
- Visual Studio 2008 SP1 (qui inclut SQL Server Express 2008) ;
- Silverlight 3 RTM ;
- .NET RIA Services July '09 Preview.
Téléchargez aussi les fichiers de la démo complète.
Dans cette partie, nous allons étudier quelques évolutions intéressantes de l'application SuperEmployee que nous étions en train de développer. La première est d'ajouter une nouvelle colonne dans la table sur laquelle nous avons travaillé, et la seconde est d'ajouter une nouvelle table avec des données supplémentaires associées à chaque SuperEmployee.
Une bonne partie des détails du flux de travail pour cette évolution dépend de la DAL (couche d'accès aux données, NdT) que vous utilisez. Puisque .NET RIA Services n'est pas dépendant d'une DAL spécifique, cette partie de l'évolution peut varier un peu. Pour ce tutoriel pas à pas, je vous montrerai comment ça se passe avec Entity Framework et je vous laisserai le soin de l'adapter à votre propre DAL.
Ajout d'une nouvelle colonne▲
Depuis que j'ai créé le schéma de la table SuperEmployee il y a six mois, je trouve qu'il manque vraiment l'aspect le plus important d'un superhéros : savoir quel est son pouvoir. Je veux dire, je dois connaitre leur superpouvoir pour les embaucher, n'est-ce pas ? Voyons donc comment ajouter le superpouvoir à la base de données.
Ouvrons la base Northwind.mdf depuis le répertoire App_Data et sélectionnons « Ouvrir la définition de table » :
Ajoutons ensuite une colonne appelée « SuperPower » et définissons-la comme étant de type nvarchar(MAX).
Voilà, nous avons mis à jour le schéma de la base, il faut maintenant mettre à jour le modèle. Pour ce faire, ouvrez Nortwind.edmx et sélectionnez « Mettre à jour le modèle à partir de la base de données » :
Sélectionnez « Actualiser » :
Et on voit que notre modèle est mis à jour !
Maintenant, recompilons simplement le projet, et nous pouvons accéder à cette nouvelle propriété à partir du serveur Web dans le DomainService si nous voulons écrire de la logique d'application qui l'utilise, sinon nous pouvons y accéder directement à partir du client.
Pour commencer, ajoutons SuperPower à la liste des champs que le DataForm gère pour nous. C'est juste une mise à jour sur le DataForm dont nous avons parlé dans la partie 2 : Rich Data Query.
<
dataControls
:
DataField>
<TextBox
Text
=
"{Binding SuperPower, Mode=TwoWay}"
/>
</
dataControls
:
DataField>
Et bien sûr l'affichage marche très bien :
Et je peux maintenant ajouter un superpouvoir à plusieurs superhéros et valider pour voir les changements répercutés sur la base de données :
Ajoutons maintenant juste un peu de validation à notre nouveau membre. Dans le fichier SuperEmployeeDomainService.metadata.cs, ajoutez :
[StringLength(
25
,MinimumLength=
3
,
ErrorMessage =
"Superpower's should be between 3 and 25 characters long"
)]
public
string
SuperPower;
Compilez, exécutez, et nous avons maintenant la validation !
Revenons à notre service Astoria et à notre client WinForm de la partie 5. Que devons-nous faire pour les mettre à jour ? Eh bien, pas grand-chose. Le service Astoria est généré dynamiquement à partir du modèle, et le DataGridView est aussi dynamique dans notre cas, donc tout ce qu'il y a à faire est de mettre à jour la référence de service, et le tour est joué !
Et l'application fonctionne parfaitement. Un moyen facile de saisir beaucoup de données rapidement.
J'ai montré jusqu'ici à quel point il est facile de faire évoluer une entité pour lui ajouter un champ supplémentaire. Voyons maintenant comment ajouter une nouvelle entité complète.
Ajout d'une nouvelle entité associée▲
Pour cet exemple, je vais ajouter les informations de contact de l'agent du superhéros pour pouvoir entrer en relation avec le superhéros qu'on décide d'embaucher. La première étape est d'ajouter une table à notre base de données pour stocker les informations de contact :
Il faut ensuite l'associer à la table SuperEmployees via une clé étrangère.
On peut maintenant mettre à jour notre modèle Entity Framework :
On veut ajouter la nouvelle table Contact :
On veut également mettre à jour notre classe SuperEmployee pour récupérer la clé étrangère pour le Contact :
Cela nous donne ce modèle :
Nous faisons une recompilation complète et tout devrait être bon.
Intégrons maintenant la table Contact à notre application.
Tout d'abord nous devons ajouter la logique à notre DomainService.
public
IQueryable<
SuperEmployee>
GetSuperEmployees
(
)
{
return
this
.
Context.
SuperEmployeeSet
.
Include
(
"Contact"
)
.
Where
(
emp=>
emp.
Issues>
100
)
.
OrderBy
(
emp=>
emp.
EmployeeID);
}
Remarquez qu'à la quatrième ligne, on a indiqué à Entity Framework d'inclure le Contact associé quand on récupère chaque SuperEmployee de la base de données.
Maintenant, dans SuperEmployeeMetadata.cs, il faut ajouter des métadonnées pour dire à RIA Services d'inclure les informations de contact dans les données qu'il envoie au client :
public
void
InsertContact
(
Contact contact)
{
this
.
Context.
AddToContact
(
contact);
}
public
void
UpdateContact
(
Contact currentContact)
{
this
.
Context.
AttachAsModified
(
currentContact,
ChangeSet.
GetOriginal
(
currentContact));
}
Super, la partie serveur est terminée, maintenant repassons au client. Ce que je veux faire ici, c'est ajouter un élément graphique au DataForm des détails pour afficher les informations de contact.
À l'intérieur du DataForm dans Home.xaml, ajoutons un bouton pour éditer les informations de contact :
<Button
Content
=
"Edit Contact Information..."
Width
=
"205"
Height
=
"28"
Margin
=
"15,10,0,0"
HorizontalAlignment
=
"Left"
Click
=
"EditContact_Click"
>
Il faut maintenant gérer l'évènement Click du bouton. Ici on va créer une fenêtre enfant pour afficher un formulaire pour visualiser et modifier les informations de contact :
private
void
EditContact_Click
(
object
sender,
RoutedEventArgs e)
{
var
emp =
dataForm1.
CurrentItem as
SuperEmployee;
if
(
emp.
Contact ==
null
)
emp.
Contact =
new
Contact
(
);
var
w =
new
EditContactWindow
(
emp.
Contact);
w.
Show
(
);
w.
Closed +=
EditContact_Closed;
}
void
EditContact_Closed
(
object
sender,
EventArgs e)
{
var
win =
sender as
EditContactWindow;
var
emp =
dataForm1.
CurrentItem as
SuperEmployee;
if
(
win.
DialogResult ==
true
)
{
emp.
Contact =
win.
Contact;
}
}
Ajoutez une nouvelle fenêtre enfant et appelez-la EditContactWindow. Voici son code-behind :
public
partial
class
EditContactWindow :
ChildWindow
{
public
Contact Contact;
public
EditContactWindow
(
Contact contact)
{
InitializeComponent
(
);
Contact =
contact;
this
.
LayoutRoot.
DataContext =
Contact;
}
private
void
OKButton_Click
(
object
sender,
RoutedEventArgs e)
{
this
.
DialogResult =
true
;
dataform1.
CommitEdit
(
);
}
private
void
CancelButton_Click
(
object
sender,
RoutedEventArgs e)
{
this
.
DialogResult =
false
;
}
}
Et le XAML est simplement un DataForm pour afficher les données :
<
dataFormToolkit
:
DataForm
x
:
Name
=
"dataform1"
CurrentItem
=
"{Binding}"
>
<
dataControls
:
DataForm.EditTemplate>
<DataTemplate>
<StackPanel>
<
dataControls
:
DataField>
<TextBox
Text
=
"{Binding ContactName, Mode=TwoWay}"
/>
</
dataControls
:
DataField>
<
dataControls
:
DataField>
<TextBox
Text
=
"{Binding ContactTitle, Mode=TwoWay}"
/>
</
dataControls
:
DataField>
<
dataControls
:
DataField>
<TextBox
Text
=
"{Binding Address, Mode=TwoWay}"
/>
</
dataControls
:
DataField>
<
dataControls
:
DataField>
<TextBox
Text
=
"{Binding City, Mode=TwoWay}"
/>
</
dataControls
:
DataField>
<
dataControls
:
DataField>
<TextBox
Text
=
"{Binding Region, Mode=TwoWay}"
/>
</
dataControls
:
DataField>
<
dataControls
:
DataField>
<TextBox
Text
=
"{Binding PostalCode, Mode=TwoWay}"
/>
</
dataControls
:
DataField>
<
dataControls
:
DataField>
<TextBox
Text
=
"{Binding Phone, Mode=TwoWay}"
/>
</
dataControls
:
DataField>
</StackPanel>
</DataTemplate>
</
dataControls
:
DataForm.EditTemplate>
</
dataFormToolkit
:
DataForm>
Et le résultat est magnifique !
Remarquez que côté serveur, dans SuperEmployeeDomainService.metadata.cs, j'ai précisé des métadonnées pour contrôler comment le contact est affiché. C'est aussi là que je mettrais les paramètres de validation.
[MetadataTypeAttribute(
typeof
(Contact.ContactMetadata))]
public
partial
class
Contact
{
internal
sealed
class
ContactMetadata
{
// Metadata classes are not meant to be instantiated.
private
ContactMetadata
(
)
{
}
[Display(Name=
"Name"
)]
public
object
ContactName;
[Display(Name =
"Title"
)]
public
object
ContactTitle;
public
object
Address;
public
object
City;
[Display(Name =
"State"
)]
public
object
Region;
[Display(Name =
"Zip Code"
)]
public
object
PostalCode;
public
object
Phone;
}
}
C'est fini !
Dans cette partie nous avons vu comment faire évoluer petit à petit une application RIA Services + Silverlight. J'ai montré comment ajouter une nouvelle colonne à une table existante et comment ajouter une nouvelle table.
Profitez-en !
Conclusion▲
Ceci conclut la dix-septième partie de cette série. La partie suivante traitera des fournisseurs Linq personnalisé.
Remerciements▲
Je tiens ici à remercier Brad Abrams de nous avoir autorisés à traduire son article.
Je remercie également ClaudeLELOUP et jacques_jean pour leur relecture et leurs propositions.