Microsoft Trainer e Software Architect
Sviluppatore professionista dal 2001 con VB6, SQL 2000 e Access creando applicazioni gestionali di varia natura. Passando rapidamente a .NET, windows e web, ho poi espanso le mie esperienze su Compact Framework, SQL Server Mobile ed infine BizTalk Server.
Negli ultimi anni mi sono focalizzato sempre più sullo sviluppo distribuito ed enterprise conseguendo nel contempo le seguenti certificazioni:
Microsoft Certified Trainer (MCT)Microsoft MCPD .NET 3.5 Enterprise Applications DeveloperMicrosoft MCTS .NET 3.5 WCF Applications DevelopmentMicrosoft MCTS .NET 3.5 ASP.NET Applications DevelopmentMicrosoft MCTS .NET 3.5 ADO.NET Applications DevelopmentMicrosoft MCTS .NET 3.5 Windows Applications DevelopmentMicrosoft MCTS .NET 2.0 Distributed Applications DevelopmentMicrosoft MCP .NET
Ciao a tutti
Disaccoppiare e fattorizzare sono le parole più frequenti per uno sviluppatore
Nel caso dell’accesso ai dati, è buona norma avere uno strato per dialogare con il motore di persistenza, in questo caso EF
Il TableDataGateway è un pattern molto semplice per dialogare con il DB. Facciamo un esempio d’uso:
using (var context = new TestDBEntities()) { using (var gateway = new TableDataGateway<Persone>(context)) { var persone = gateway.Select().Take(10); var persona1 = persone.First();
persona1.Nome += " modificato"; var saveResult = gateway.Update(persona1);
var newpersona = new Persone { Nome = "pippo", Cognome = "disney", Età = 1161 }; var insertResult = gateway.Insert(newpersona);
var deleteResult = gateway.Delete(newpersona); } }
ho il mio context ed ho il mio gateway che è in grado di fare tutto il lavoro da solo per effettuare le operazioni di CRUD.
vediamo la classe tabledatagateway:
public class TableDataGateway<T> : IDisposable where T : EntityObject { internal readonly ObjectContext Context;
public TableDataGateway(ObjectContext context) { Context = context; }
protected virtual ObjectSet<X> ObjectSetOf<X>() where X : EntityObject { //trovo l'objectset relativo alla mia entity var p = Context.GetType().GetProperties().FirstOrDefault(x => x.PropertyType == typeof(ObjectSet<T>)); if (p != null) return (ObjectSet<X>)p.GetValue(Context, null); else return null; }
public virtual IQueryable<T> Select() { return ObjectSetOf<T>(); }
public virtual bool Delete(T arg) { //faccio l'attach dell'entity if(arg.EntityState== System.Data.EntityState.Detached) ObjectSetOf<T>().Attach(arg);
ObjectSetOf<T>().DeleteObject(arg); return Context.SaveChanges() > 0; }
public virtual bool Insert(T arg) { ObjectSetOf<T>().AddObject(arg); return Context.SaveChanges() > 0; }
public virtual bool Update(T arg) { object original; //per effettuare l'update correttamente cerco di trovare l'originale non modificato sul server if (Context.TryGetObjectByKey(arg.EntityKey, out original)) { //aggiorno l'originale con i valori modificati del mio oggetto corrente original = ObjectSetOf<T>().ApplyCurrentValues(arg); //salvo le modifiche var risp = Context.SaveChanges() > 0; //faccio refresh del mio oggetto così da leggere eventuali modifiche altrui sul server Context.Refresh(RefreshMode.StoreWins, arg); return risp; } else throw new ArgumentException("Unable to find given entity by it's entitykey!"); }
public void Dispose() { } }
è possibile estendere la classe per dare maggior potenzialità, così come è possibile fare cache delle property info del context per maggiori performance, ma lascio a voi le personalizzazioni
a presto