Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 11
  1. #1

    Entity Framework: risalire al nome della tabella dal modello concettuale

    Ciao a tutti, sto sviluppando la mia prima applicazione che implementa Entity Framework. Ho già definito tutto il modello (concettuale, archiviazione e mapping), ma volevo implementare un sistema di cancellazione logica, che EF nativamente non supporta (che io sappia).
    Quindi ho fatto l'override del metodo SaveChanges per andare ad eseguire la query direttamente sul db in caso di cancellazione di modo da non cancellare veramente il record, ma fare un UPDATE e marcare il mio record come cancellato.

    Il problema però che quando intercetto l'eliminazione sto lavorando ovviamente con i miei oggetti "dal lato concettuale" e (come è giusto che sia) non conosco quale sia la loro rappresentazione sul database. Come faccio a risalire al nome della tabella in cui sono archiviati i miei dati riguardanti l'oggetto che sto eliminando, così da poter costruire la query di UPDATE?

    Ecco il codice... vorrei sostituire quei ??????????????....

    codice:
    public override int SaveChanges(System.Data.Objects.SaveOptions options)
    {
    	var deleted = this.ObjectStateManager.GetObjectStateEntries(EntityState.Deleted);
    
    	foreach (var deletedItem in deleted)
    	{
    		var storeItem = this.MetadataWorkspace.GetItems<EntityType>(DataSpace.SSpace).Where(et => et.Name == ?????????).FirstOrDefault();
    		if (storeItem != null)
    		{
    			const string deleteSql = "UPDATE {0} SET recordDeleted = 1 WHERE 1=1 {1}";
    
    			// Trovo la proprieta
    			var deleteProperty = storeItem.Properties.Where(ep => ep.Name == "recordDeleted").FirstOrDefault();
    			if (deleteProperty != null)
    			{
    				// Ciclo tutte le chiavi
    				StringBuilder strWhere = new StringBuilder();
    				foreach (EntityKeyMember key in deletedItem.EntityKey.EntityKeyValues)
    				{
    					string strKey = " AND {0} = {1}";
    					strWhere.Append(string.Format(strKey, key.Key, key.Value));
    				}
    
    				// Eseguo la Query
    				this.ExecuteStoreCommand(string.Format(deleteSql, storeItem.Name, strWhere.ToString()));
    			
    				// Cambio lo State dell'Entità
    				deletedItem.ChangeState(EntityState.Unchanged);
    			}
    		}
    	}
    
    	return base.SaveChanges(options);
    }
    P.S. Il linguaggio non mi interessa.... io sto usando C#, ma se mi offrite una soluzione in VB.NET mi va bene lo stesso... mi arrangio.
    La verita' è che... tu sei il debole, e io sono la tirannia degli uomini malvagi, ma ci sto provando ringo, ci sto provando con grandissima fatica a diventare il pastore..

  2. #2
    Per gestire questa logica, hai considerato la possibilità di usare un set di stored procedure CRUD sul DBMS (che immagino sia Sql Server) ?

    http://thedatafarm.com/LearnEntityFr...ty-data-model/

  3. #3
    Originariamente inviato da Andrea Simonassi
    Per gestire questa logica, hai considerato la possibilità di usare un set di stored procedure CRUD sul DBMS (che immagino sia Sql Server) ?

    http://thedatafarm.com/LearnEntityFr...ty-data-model/
    Si ci avevo già pensato, ma dovendo farlo su praticamente tutte le tabelle volevo evitare di farmi 3 stored procedure per ogni tabella... potrebbe diventare una cosa lunga...

    Inoltre, se un giorno volessi passare ad un DBMS diverso, vorrei una cosa facilmente adattabile.
    La verita' è che... tu sei il debole, e io sono la tirannia degli uomini malvagi, ma ci sto provando ringo, ci sto provando con grandissima fatica a diventare il pastore..

  4. #4
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,477
    Originariamente inviato da 8matt5
    Inoltre, se un giorno volessi passare ad un DBMS diverso, vorrei una cosa facilmente adattabile.
    Più scrivi SQL, meno sarà adattabile.

    A parte questo, perché elimini gli oggetti con una query SQL invece di farlo attraverso EF?
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Home | Blog | Delphi Podcast | Twitch | Altro...

  5. #5
    Originariamente inviato da 8matt5
    potrebbe diventare una cosa lunga...
    Un generatore automatico potrebbe risolvere il problema.

    Ad ogni modo se vuoi risalire al nome della tabella modificata devi usare ObjectStateManager e interrogarlo per sapere quali entita sono state modificate.

    In ogni modo questi framework, semplificheranno anche il 95% del lavoro, ma quel restante 5% diventa tanto complicato da avermi sempre fatto pensare di evitare questi frameworks come la peste (se già so di non potere evitare quel 5%), in quanto per fare quel 5% di lavoro devi comunque essere a conoscenza della struttura fisica del DB ecc. opinioni personali.

    Ciao e buon lavoro.

  6. #6
    Originariamente inviato da Andrea Simonassi
    Un generatore automatico potrebbe risolvere il problema.

    Ad ogni modo se vuoi risalire al nome della tabella modificata devi usare ObjectStateManager e interrogarlo per sapere quali entita sono state modificate.

    In ogni modo questi framework, semplificheranno anche il 95% del lavoro, ma quel restante 5% diventa tanto complicato da avermi sempre fatto pensare di evitare questi frameworks come la peste (se già so di non potere evitare quel 5%), in quanto per fare quel 5% di lavoro devi comunque essere a conoscenza della struttura fisica del DB ecc. opinioni personali.

    Ciao e buon lavoro.
    Grazie della dritta. Ho esplorato invano quegli oggetti in lungo e in largo per trovare quel nome. Stasera mi concentro su quello poi ti so dire.
    Comunque lo scopo di EF non è a mio avviso quello di semplificare la gestione dei dati, ma di separare la logica che governa gli oggetti da quella che serve per archiviarli.



    Originariamente inviato da alka
    Più scrivi SQL, meno sarà adattabile.

    A parte questo, perché elimini gli oggetti con una query SQL invece di farlo attraverso EF?
    Usando direttamente EF devo inserire nel mio oggetto una proprietà inutile (quella che mi dice se il record è cancellato o no). Inoltre questa proprietà non posso proprio metterla visto che la uso nel mapping condition.

    Scrivere Sql specifico per ogni tipo di dmbs mi assicura la possibilità di utilizzarne un qualsiasi tipo, usare le stored procedure mi impedisce di usare quelli che non le supportano.
    La verita' è che... tu sei il debole, e io sono la tirannia degli uomini malvagi, ma ci sto provando ringo, ci sto provando con grandissima fatica a diventare il pastore..

  7. #7
    Originariamente inviato da 8matt5

    Comunque lo scopo di EF non è a mio avviso quello di semplificare la gestione dei dati, ma di separare la logica che governa gli oggetti da quella che serve per archiviarli.

    .
    Si, ma non è l'unico modo per separare le due logiche. A questo mi riferisco.

  8. #8
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,477
    Originariamente inviato da 8matt5
    Usando direttamente EF devo inserire nel mio oggetto una proprietà inutile (quella che mi dice se il record è cancellato o no).
    Se il tuo oggetto prevede la possibilità di essere "cancellato" logicamente, e non fisicamente, quella proprietà non è inutile, in quanto esprime esattamente questo stato.

    Originariamente inviato da 8matt5
    Inoltre questa proprietà non posso proprio metterla visto che la uso nel mapping condition.
    Se prevedi una cancellazione logica e non fisica dei record, il campo dovrebbe esistere sia su DB che sull'oggetto.

    Originariamente inviato da 8matt5
    Scrivere Sql specifico per ogni tipo di dmbs mi assicura la possibilità di utilizzarne un qualsiasi tipo
    Sì, ma poi dovrai codificare SQL specifico in base al DBMS che vai a indirizzare.
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Home | Blog | Delphi Podcast | Twitch | Altro...

  9. #9
    Originariamente inviato da alka
    Se il tuo oggetto prevede la possibilità di essere "cancellato" logicamente, e non fisicamente, quella proprietà non è inutile, in quanto esprime esattamente questo stato.
    Questa cosa della cancellazione logica deve essere completamente trasparente al programma.
    Io non avrò mai bisogno di indagare sullo stato della mia colonna "recordDeleted" semplicemente perchè all'interno del mio insieme di oggetti ci saranno solamente quelli con il campo "recordDeleted" = 0. Questo perché ho inserito una mapping condition che me li filtra. è per questo che EF non mi permette neanche di tenerlo tra le proprietà, perché non ha senso che io voglia leggere o modificare quel campo. Tutti gli oggetti hanno il campo settato a 0 e tutti i nuovi oggetti che creerò saranno automaticamente settati a 0.

    Quello che voglio ottenere (che in realtà in parte ho già ottenuto) e che io chiamo DeleteObject() e invece di eliminarmi fisicamente il record, me lo marchi come eliminato. La query l'ho già fatta e volendo ho anche già la logica per gestire più tipi di connessione diversa. L'unica cosa è che non so come risalire al nome della tabella.
    Poi magari questo non è il metodo migliore, ho approcciato da poco EF, ma quello che voglio ottenere è più o meno questo.

    Originariamente inviato da alka
    Se prevedi una cancellazione logica e non fisica dei record, il campo dovrebbe esistere sia su DB che sull'oggetto.
    vedi sopra.

    Originariamente inviato da alka
    Sì, ma poi dovrai codificare SQL specifico in base al DBMS che vai a indirizzare.
    Questo non è assolutamente un problema. Intanto non ho la pretesa di crere un'applicazione che fin da subito sia compatibile con ogni DBMS presente in natura. Basterà implementare un "driver" specifico quando voglio estendere la compatibilità ad un determinato DBMS. Sapere a quale DBMS mi sto connettendo è facile e la query da eseguire è talmente banale che probabilmente sarà sempre la stessa per tutti... la sintassi dell'UPDATE penso sia praticamente identica per tutti.
    La verita' è che... tu sei il debole, e io sono la tirannia degli uomini malvagi, ma ci sto provando ringo, ci sto provando con grandissima fatica a diventare il pastore..

  10. #10
    Utente di HTML.it L'avatar di rsdpzed
    Registrato dal
    Aug 2001
    Messaggi
    764
    Se non puoi tirare fuori questa info dai metadati potresti sempre crearti una dictionary<Type, string> interna alla classe che wrappa il context, e interroghi molto piu semplicemente quella invece che i metadati. La costruisci una tantum direttamente nel codice o la carichi da un file xml. Un altro elemento da tenere sincronizzato al modello e al db? fosse solo quello il problema...

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.