20

Oct

Un Semplice TableDataGateway per gestire il crud sulla nostra base dati EntityFramework

 

Ciao a tutti

 

Disaccoppiare e fattorizzare sono le parole più frequenti per uno sviluppatore Sorriso

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(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 : IDisposable
    where T : EntityObject
{
    internal readonly ObjectContext Context;

    public TableDataGateway(ObjectContext context) { Context = context; }

    protected virtual ObjectSet ObjectSetOf()
        where X : EntityObject
    {
        //trovo l'objectset relativo alla mia entity
        var p = Context.GetType().GetProperties().FirstOrDefault(x => x.PropertyType == typeof(ObjectSet));
        if (p != null)
            return (ObjectSet)p.GetValue(Context, null);
        else
            return null;
    }

    public virtual IQueryable Select() { return ObjectSetOf(); }

    public virtual bool Delete(T arg)
    {
        //faccio l'attach dell'entity
        if(arg.EntityState== System.Data.EntityState.Detached)
            ObjectSetOf().Attach(arg);

        ObjectSetOf().DeleteObject(arg);
        return Context.SaveChanges() > 0;
    }

    public virtual bool Insert(T arg)
    {
        ObjectSetOf().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().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 Sorriso

 

a presto

by Antonio Esposito on 10/20/2011