asp.net mvc 4 - Generic Repository EF 5 - Update Entity And It's Complex/Scalar/Navigation Properties -


i'm trying find easy solution updating entity + included properties in solution. i've created generic repository dbcontext (database). update parent entity, not handling changes on child properties. there way handle or track changes?

example code updating child propery: (look @ comment - example code)


    [httpput]     public httpresponsemessage putbrand(brand brand)     {         if (!modelstate.isvalid)         {             return request.createerrorresponse(httpstatuscode.badrequest, modelstate);         }          try         {             // example code             brand.brandsizes.firstordefault().name = "i'm test";               // add values             brand.state = state.changed;             brand.datechanged = datetime.now;              // update             brand = _brandservice.updatebrand(brand);             // save             _brandservice.savebrandchanges();             // signalr             hub.clients.all.updatebrand(brand);              return request.createresponse<brand>(httpstatuscode.ok, brand);         }         catch (exception ex)         {             return request.createresponse(httpstatuscode.internalservererror, ex.message);         }     } 

context:


public class erpcontext : dbcontext {     #region catalog      public dbset<brand> brands { get; set; }      public dbset<brandsize> brandsizes { get; set; }      public dbset<brandsizeoption> brandsizeoptions { get; set; }      public dbset<brandtierprice> brandtierprices { get; set; }      #endregion catalog       public erpcontext()         : base("db-erp")     {         configuration.lazyloadingenabled = false;         configuration.proxycreationenabled = false;     }        protected override void onmodelcreating(dbmodelbuilder modelbuilder)     {          modelbuilder.conventions.remove<pluralizingtablenameconvention>();       } } 

generic repository:


public class erprepository<t> : irepository<t> t : class {     #region fields      private dbset<t> _dbset;     private dbcontext _datacontext;      #endregion fields      #region ctor      public erprepository(dbcontext datacontext)     {         if (datacontext == null)         {             throw new argumentnullexception("datacontext", "datacontext cannot null");         }          _datacontext = datacontext;         _dbset = _datacontext.set<t>();     }      #endregion ctor      #region methods      public t add(t item)     {         return _dbset.add(item);     }      public t delete(t item)     {         return _dbset.remove(item);     }      public t update(t item)     {         var updated = _dbset.attach(item);         _datacontext.entry(item).state = entitystate.modified;         return updated;     }      public iqueryable<t> query(params expression<func<t, object>>[] includes)     {         var query = _dbset;          if (includes != null)         {             includes.tolist().foreach(x => query.include(x).load());         }          return query;     }      public void savechanges()     {         _datacontext.savechanges();     }      #endregion methods } 

model:


public class brand {     #region ctr      public brand()     {         brandsizes = new list<brandsize>();         brandtierprices = new list<brandtierprice>();     }      #endregion ctr      #region properties      public int id { get; set; }      public string name { get; set; }      public string description { get; set; }      public int? logoid { get; set; }      public int displayorder { get; set; }      public bool deleted { get; set; }      public bool locked { get; set; }      public state state { get; set; }      public datetime datechanged { get; set; }      public datetime datecreated { get; set; }      #endregion properties      #region mapping      public virtual picture logo { get; set; }      public virtual list<brandsize> brandsizes { get; set; }      public virtual list<brandtierprice> brandtierprices { get; set; }      #endregion mapping } 

brandservice:


public partial class brandservice : ibrandservice {     #region fields      private readonly irepository<brand> _brandrepository;     private readonly irepository<brandsize> _brandsizerepository;     private readonly irepository<brandsizeoption> _brandsizeoptionrepository;      #endregion fields      #region ctor      public brandservice(irepository<brand> brandrepository, irepository<brandsize> brandsizerepository, irepository<brandsizeoption> brandsizeoptionrepository)     {         _brandrepository = brandrepository;         _brandsizerepository = brandsizerepository;         _brandsizeoptionrepository = brandsizeoptionrepository;     }      #endregion ctor      #region methods       public virtual ienumerable<brand> getallbrands()     {         return _brandrepository.query(x => x.brandsizes);          //return _brandrepository.query();     }      public virtual brand getbrandbyid(int id)     {         return _brandrepository.query().where(x => x.id == id).firstordefault();     }      public virtual brand insertbrand(brand brand)     {         return _brandrepository.add(brand);     }      public virtual brand updatebrand(brand brand)     {         return _brandrepository.update(brand);     }      public virtual brand deletebrand(brand brand)     {         return _brandrepository.delete(brand);     }      public virtual void savebrandchanges()     {         _brandrepository.savechanges();     }        #endregion methods } 

create iobjectwithstate interface , state enum track changes manually:

public interface iobjectwithstate {     state state { get; set; } }  public enum state {     added,     unchanged,     modified,     deleted } 

and implement interface in every mapped entity

 public class brand:iobjectwithstate { .... [notmapped]     public state state { get; set; }} 

and add these 2 helper methods convert state , apply changes in entire graph:

public static entitystate convertstate(state state)     {         switch (state)         {             case state.added :                 return entitystate.added;             case state.deleted:                 return entitystate.deleted;             case state.modified:                 return entitystate.modified;             case state.unchanged:                 return entitystate.unchanged;             default:                 return entitystate.unchanged;         }     }      public static void applystatechanges(this dbcontext context)     {         foreach (var entry in context.changetracker.entries<iobjectwithstate>())         {             iobjectwithstate stateinfo = entry.entity;             entry.state = statehelpers.convertstate(stateinfo.state);         }     } 

and when update or insert object edit state of object.state = state.modified; , modify insert or update method this:

 public void insertorupdate(t entity, bool isgraph)     {         if (((iobjectwithstate)entity).state == state.added)         {             datacontext.entry(entity).state = system.data.entity.entitystate.added;         }         else         {             dbset.add(entity);             datacontext.entry(entity).state = system.data.entity.entitystate.modified;         }         //this method change state of every changed object         if (isgraph)             applystatechanges(datacontext);         datacontext.commit();     } 

Comments

Popular posts from this blog

php - get table cell data from and place a copy in another table -

javascript - Mootools wait with Fx.Morph start -

php - Navigate throught databse rows -