25 messaggi dal 14 luglio 2011
ciao a tutti, avrei bisogno di una dritta, più che altro una best practice da seguire:
nella mia applicazione web, strutturata a 3livelli, ho configurato nhibernate per gestire la persistenza dei dati; ora mi trovo a dover salvare il contenuto di una gridview e mi chiedevo.. quale è il modo migliore di procedere?
. Ciclo tutte le righe e ad ogni giro chiamo il mio metodo di manager?
. Mappo l'intero contenuto della gridview in una IList e lo passo al mio metodo di manager?(questo punto come lo sviluppereste?)

Grazie!
11.886 messaggi dal 09 febbraio 2002
Contributi
cleaner ha scritto:

. Ciclo tutte le righe e ad ogni giro chiamo il mio metodo di manager?

sì, a patto che poi il manager non vada a persistere nel db ogni riga singolarmente. Anche se invochi più volte il tuo metodo del manager, le righe dovranno infine essere persistite transazionalmente, o comunque in un unico batch.

Se metti in pratica questo accorgimento, aggiungere un ipotetico metodo .AddAll(ICollection<Entita>) al tuo manager diventerà banale perché, internamente, non dovrà far altro che ciclare esso stesso la collezione e invocare l'.Add con ciascuna entità.

Guarda questo articolo di Ayende, c'è anche del codice da scaricare con svn per prendere spunto.
Leggi in particolare il paragrafo "Unit of work to the rescuse". Lì usa il pattern Unit of work per gestire la sessione NHibernate e fare in modo che ad ogni .Add venga impiegata sempre la stessa.

ciao,
Modificato da BrightSoul il 31 ottobre 2011 21.53 -

Enjoy learning and just keep making
25 messaggi dal 14 luglio 2011
mm.. quanto mi proponi, cioè un metodo nel mio manager del tipo .AddAll(ICollection<Entita>)
non andrebbe bene, perchè nella struttura della mia applicazione non vedo nella presentation il dominio, cioè non saprei come "linkare" la mia entità..dato che questa si vede solo nella business logic.
11.886 messaggi dal 09 febbraio 2002
Contributi
cleaner ha scritto:
cioè non saprei come "linkare" la mia entità..dato che questa si vede solo nella business logic.

ok, allora forse dovresti lavorare con lo stesso tipo di dato che avevi ottenuto dalla business logic e che hai bindato alla gridview.

Se si trattava di un DTO, raccogli le informazioni dalla gridview, riassembli il DTO e lo ripassi al business layer (fortunatamente in asp.net 4.5 avremo il model binder anche in webforms e questo lavoro di riassemblamento verrà fatto automaticamente).
Se era invece era una DataTable, ripassi una DataTable e così via. Sarebbe preferibile un DTO o, in alternativa, nel business layer potresti fare in modo che il metodo .Add accetti tanti parametri quante sono le informazioni richieste. Ad esempio, per l'inserimento di una persona:
public void Add(string Nome, string Cognome, int Eta, string CodiceFiscale)


ciao
Modificato da BrightSoul il 16 novembre 2011 22.13 -

Enjoy learning and just keep making
25 messaggi dal 14 luglio 2011
ciao prima di tutto grazie per l'aiuto.
in secondo luogo per il momento preferirei non usarli i dto; mi vorrei appoggiare ad un datatable magari.. per fare il binding della gridview ho usato un ObjectDataSource fatto in questo modo:

<asp:ObjectDataSource   
                    ID="ObjectDataSourceDGWA"  
                    runat="server"  
                    TypeName="Fifa.Business.PlayerManager"  
                    SelectMethod="GetPlayer">
                    <SelectParameters>
                        <asp:ControlParameter ControlID="DDLSectionTeamNewMatchA" 
                                              PropertyName="SelectedValue" 
                                              Name="Id_squadra" Type="String"/>



il tipo restituito non è uguale..però potrebbe starci comunque che dici?
grazie ancora.
11.886 messaggi dal 09 febbraio 2002
Contributi
ciao,

cleaner ha scritto:

mi vorrei appoggiare ad un datatable magari..

Però vorrei capire come mai vorresti usare un DataTable...

Guarda il SelectMethod del tuo ObjectDataSource, si chiama GetPlayer. Immagino che restituisca un IList<Player> o qualcosa di simile. Secondo me dovresti continuare ad usare l'ObjectDataSource così come hai iniziato a fare. Aggiungi gli attributi UpdateMethod e InsertMethod all'ObjectDataSource e poi legali ai nuovi metodi UpdatePlayer e AddPlayer che creerai all'interno di Fifa.Business.PlayerManager. Questi due nuovi metodi dovranno accettare un'unico parametro di tipo Player oppure, come ti dicevo ieri, tanti parametri: uno per ogni proprietà di Player.

E' Visual Studio stesso che ti consiglia di farlo, guarda questa immagine, appare quando vai a configurare l'ObjectDataSource dal designer.
http://i1.asp.net/asp.net/images/dataaccess/16fig08vb.png
Si legge appunto:

The method should accept a parameter for each property of the data object, or a single parameter which is the data object to insert


Come posso convincerti di questo fatto :) Qui c'è un tutorial completo che illustra da vicino il tuo scenario: GridView+ObjectDataSource+BusinessLayer.
http://www.asp.net/data-access/tutorials/an-overview-of-inserting-updating-and-deleting-data-vb

ciao,

Enjoy learning and just keep making
25 messaggi dal 14 luglio 2011
ciao, prima di tutto ancora grazie per il supporto che mi stai fornendo; in secondo luogo io potrei utilizzare l'objdatasource e sarebbe veramente comodo.. tuttavia io devo salvare le modifiche tutte in un colpo solo:
ho creato il mio metodo nel manager
        [DataObjectMethod(DataObjectMethodType.Update)]
        public IList<Player> UpdateStatisticsPlayers(IList<Player> player)
        {
            using (ISession session = SessionHelper.OpenSession())
            using (ITransaction transaction = session.BeginTransaction())
            {
                session.Update(player);
                transaction.Commit();
            }
            return player;
        }

al quale passerò una collection di player da aggiornare, ma:

1) In questo contesto l'objdatasource non viene in aiuto giusto?
2) Sul click "Salva" dovrò ciclare la mia gridview e passare il tutto a UpdateStatisticsPlayers concordi?

Se si può in quale modo usare ObjectDataSource posso sicuramente optare per questa opzione grazie;)
11.886 messaggi dal 09 febbraio 2002
Contributi
ciao,

cleaner ha scritto:

Sul click "Salva" dovrò ciclare la mia gridview e passare il tutto a UpdateStatisticsPlayers concordi?

sì, indubbiamente puoi risolvere anche in questo modo. Cicli le righe della gridview, raccogli dal suo interno i valori dei campi, istanzi un nuovo Player per ogni riga, ne valorizzi le proprietà con i valori che hai estratto, aggiungi il Player così formato ad una lista, passi la lista all'UpdateStatisticsPlayers. Così tutti i Player verranno aggiornati nella stessa transazione.

= oppure =

Lasci che siano la GridView e l'ObjectDataSource a fare tutto questo lavoro per te. Alla pressione del bottone di salvataggio, invoca l'.UpdateRow per ogni riga. Fine.

for (int i = 0; i < tuaGridView.Rows.Count; i++) { 
  tuaGridView.UpdateRow(i, true);
}
Invocare l'UpdateRow farà in modo che la GridView passi i valori della riga all'ObjectDataSource che si preoccuperà di istanziare un Player e inserirci dentro tutti i valori che ha ricevuto. Contestualmente, invocherà un metodo UpdateStatisticsPlayer sul tuo manager.

[DataObjectMethod(DataObjectMethodType.Update)]
public void UpdateStatisticsPlayer(Player player){
  //qui il codice per l'update del singolo player
  session.Save(player);
}


Se scegli questo secondo sistema bisogna tener conto di due cose:
  • Il primo è facile: bisogna che sull'ObjectDataSource tu metta l'attributo DataObjectTypeName per indicare il tipo di oggetto (Player) con cui ha a che fare. Quindi per esempio lo valorizzerai così... DataObjectTypeName="NomeNamespace.Player". Ah, ovviamente tutto questo è valido se Player ha un costruttore pubblico, cioè se puoi crearne liberamente delle istanze anche essendo al di fuori dello strato di business logic. Altrimenti puoi creare un metodo UpdateStatisticsPlayer che accetti tanti parametri, uno per ogni proprietà.
  • Il secondo è che, aggiornando i Player singolarmente, ottieni ogni volta una sessione diversa e quindi non verranno persistiti transazionalmente nel database. Per evitare questo problema, segui l'articolo che ti avevo postato l'altra volta. Eccolo qui:
    http://nhibernate.hibernatingrhinos.com/27/the-repository-pattern
    Leggi il paragrafo "The Unity of work to the rescue" e anche il capoverso precedente. Così facendo otterrai sempre la stessa sessione ad ogni esecuzione di UpdateStatisticsPlayer.


Deciti tu se impiegare la prima o la seconda soluzione.
La seconda mi sembra più elegante e ti rende più libero. Allo strato di presentazione non deve importare nulla di transazioni e ORM, né deve preoccuparsene, ma deve poter aggiungere oggetti quando e come vuole, secondo me.

ciao,
Modificato da BrightSoul il 19 novembre 2011 15.50 -

Enjoy learning and just keep making

Torna al forum | Feed RSS

ASPItalia.com non è responsabile per il contenuto dei messaggi presenti su questo servizio, non avendo nessun controllo sui messaggi postati nei propri forum, che rappresentano l'espressione del pensiero degli autori.