예제 #1
0
        public bool Update(T obj, bool delaySave = false)
        {
            //using (WVCContext context = new WVCContext()) {
            WVCContext context = ContextFactory.Instance;

            //_context = context.Set<T>();
            // Drawback:  setting the state to Modified forces that all properties are sent to the DB in an UPDATE statement, no matter if they changed or not
            context.Entry(obj).State = System.Data.Entity.EntityState.Modified;
            if (!delaySave)
            {
                SaveChanges();
            }
            return(true);
        }
예제 #2
0
        public void Destroy <T>(T obj, bool delaySave = false) where T : BaseEntity
        {
            WVCContext _context   = ContextFactory.Instance;
            Type       entityType = typeof(T).GetGenericArguments()[0];
            var        entry      = _context.Entry <T>(obj);

            if (entry.State == System.Data.Entity.EntityState.Detached)
            {
                _context.Set(typeof(T)).Attach(entry.Entity);
            }
            //_context.Set(typeof (T)).Remove(entry.Entity);
            // typeof(T) returns BaseEntity<T>. The context doesnt know about BaseEntity<T>, so it will
            // throw the following exception
            // The entity type BaseEntity`1 is not part of the model for the current context.
            // Correct code:
            _context.Set(entityType).Remove(entry.Entity);

            if (!delaySave)
            {
                SaveChanges();
            }
        }
예제 #3
0
        public void Destroy(int id, bool delaySave = false)
        {
            // Since we are creating only one context per request ( using WVCContext _context = ContextFactory.Instance;), we need to make sure that we are not
            // attaching the same entity with the same key more than once. This can occur in the cases when we fetch the entity to make sure it is valid, and then
            // some other place(eg: here in destroy), we try to attach again to delete it *
            // * the following code was being used
            // <!-- Start
            //WVCContext context = ContextFactory.Instance;
            //T entity = Activator.CreateInstance(typeof (T)) as T;
            //entity.id = id;
            ////Approach 1
            //var obj = context.Entry(entity);
            //if (obj.State == System.Data.EntityState.Detached) {
            //    context.Set(typeof (T)).Attach(obj.Entity); -- Error ** was being thrown
            //}
            //context.Set(typeof (T)).Remove(obj.Entity);
            // END -->
            // ** An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key.

            // The reason in that If you load the entity from the context you cannot attach an entity with the same key again. The first entity is still kept in internal context cache and context can hold only one instance with given key value per type (it is called identity map and it is  described  here : http://stackoverflow.com/questions/3653009/entity-framework-and-connection-pooling/3653392#3653392
            // You can solve it by detaching former instance but you don't have to. If you only need to save new values you can use this:
            // context.Entry(oldEntity).CurrentValues.SetValues(newEntity);

            //using (WVCContext context = new WVCContext()) {
            //    T targetEntity = context.Set<T>().Find(id);
            //    context.Set(typeof(T)).Remove(targetEntity);
            //    context.SaveChanges();
            //}

            WVCContext _context = ContextFactory.Instance;
            T          entity   = Activator.CreateInstance(typeof(T)) as T;

            entity.id = id;
            // context.Entry registers the entity with the context if the entity is not already present in the context (in which case the state will be detached).
            // If you try to attach the entity to the context, but the context already contains an entity with the same key, then you will get the error **
            var entry = _context.Entry <T>(entity);

            if (entry.State == System.Data.Entity.EntityState.Detached)
            {
                var set            = _context.Set <T>();
                T   attachedEntity = set.Find(entity.id);               // You need to have access to key
                if (attachedEntity != null)
                {
                    // meaning that the entity is already present in the context, probably because of a previous get operation
                    var attachedEntry = _context.Entry(attachedEntity);
                    attachedEntity.EntityState = WVC.Framework.EntityState.Deleted;
                }
                else                                                      // the entry with the same key (entity.id) was not found in the context
                {
                    entry.State = System.Data.Entity.EntityState.Deleted; // This should attach entity
                }
            }

            if (!delaySave)
            {
                SaveChanges();
            }

            //using (WVCContext context = new WVCContext()) {
            //WVCContext context = ContextFactory.Instance;
            //T entity = Activator.CreateInstance(typeof (T)) as T;
            //entity.id = id;
            ////Approach 1
            //var obj = context.Entry(entity);
            //if (obj.State == System.Data.EntityState.Detached) {
            //    context.Set(typeof (T)).Attach(obj.Entity);
            //}
            //context.Set(typeof (T)).Remove(obj.Entity);
            //// Approach 2
            //context.Entry(entity).State = System.Data.EntityState.Deleted;
            //if (!delaySave) {
            //    SaveChanges();
            //}
        }