Recentemente mi è capitato di usare i RIA Services poggiandomi su un DB MySql che conteneva alcune semplici Stored Procedures. Una di esse però richiedeva un paio di parametri in ingresso, un tipo INT e un tipo DATA.
Con VS 2008 SP1 mi sono costruito velocemente il mio Entity Model mappando le tabelle che mi interessavano, ma giunto al punto di mappare le Stored Procedures mi sono reso conto che l'IDE non mi dava la possibilità di impostare i parametri in ingresso alleStored Procedures; la finestra"Model Browser" infatti, permette sì di mappare le Stored Procedures tramite la comoda opzione "Create Function Import", ma solo quelle senza parametri in ingresso, mentre per le altre... attendere VS 2010 ed Entity Framework 4.0 mi dicono dalla regia.
Nel frattempo qualcosa bisognerà pur fare mi sono detto ed allora scavando scavando ho individuato una serie di passi da compiere per avere la tanto agognata SP con parametri correttamente mappata nell'EntityModel e richiamabile dal client Silverlight.
1) Importare la SP con parametri nell'Entity Model:
Come se nulla fosse usiamo la "Create Function Import", non importa se non ci lascia mappare i parametri in ingresso:

L'importante però è che il risultato venga mappato su una Entity che abbiamo già definito in precedenza:
2) Aprire il file <myEntityModel>.designer.cs e copiare...
Si, proprio così aprite il codice designer del vostro EM e copiatene il contenuto in un nuovo file .cs che chiamerete come volete. In questo nuovo file appena creato cancellate tutto tranne la partial class e i suoi costruttori e la funzione mappata sulla SP che l'IDE ha costruito per voi incurante dei parametri in ingresso. Ecco come appare la funzione nel mio esempio prima di metterci mano:
public global::System.Data.Objects.ObjectResult<bt_trainings> GetTrainingUserDate() {
return base.ExecuteFunction<bt_trainings>("GetTrainingUserDate");
}
3) Modificare la funzione mappata appena copiata nel nuovo file
Aggiungiamo i nostri parametri come nel mio esempio, facendo attenzione ad usare lo stesso nome di parametro usato per la stored procedure:
public global::System.Data.Objects.ObjectResult<bt_trainings> GetTrainingUserDate(int IDUser, DateTime dt){
ObjectParameter param1 = new ObjectParameter("iuser", IDUser);
ObjectParameter param2 = new ObjectParameter("training_date", IDUser);
ObjectParameter[] parameters = new ObjectParameter[] { param1, param2 };
return base.ExecuteFunction<bt_trainings>("GetTrainingUserDate");
}
4) Modificare il DomainService di conseguenza
Abbiamo creato il nostro EM, abbiamo poi aggiunto una partial class copiandone la struttura dal code designer.cs generato dal compilatore e abbiamo modificato la funzione mappata affinchè accolga i parametri. Ora siamo pronti per generare il Domain Service, scegliendo da "Add/New Item" la categoria "Web" e il template "Domain Service Class".
Il file generato conterrà tutto quello che serve al client Silverlight per aggiungere, aggiornare o cancellare dati dal database ma niente che riguardi, ahimè, la Stored Procedure di cui sopra. Niente paura, basta aggiungerla come nell'esempio seguente:
public IEnumerable<bt_trainings> GetTrainingUserDate(int IDUser, DateTime dt) {
ObjectResult objRes = myContextSP.GetTrainingUserDate(IDUser, dt);
return (IEnumerable<bt_trainings>)myContextSP.GeTrainingsFromUser(IDUser);
}
dove myContextSP è un'istanza della partial class che mi sono creato al punto 2.
5) Richiamare la funzione mappata nel client Silverlight
Siamo quasi arrivati; istanziamo il nostro Domain context, associamo un'entity (dello stesso tipo ritornato dalla nostra Stor Procedure con parametri) alla DataGrid che avremo inserito nella pagina. Carichiamo i dati richismando la funzione mappata sulla Stored Procedure ed il gioco è fatto!
MyDomainContext myData = new MyDomainContext();
this.dataGrid1.ItemsSource = myData.bt_trainings;
DateTime dt = new DateTime(2009,02,01);
myData.Load(myData.GetTrainingUserDateQuery(1,dt));