0

I am using MVC2 with Entity Framework 4 and am trying to implement a Repository and UnitofWork pattern. My Adds and Deletes work fine, however when the edit is called _context.SaveChanges() does save the new changes to the database. I have stepped through the code in debug and see the new values are in the object being passed to the Edit function in the controller, but when the commit is called, nothing is updated.See my code below: Thanks for your help.

Here is my IRepository

namespace EventScheduling.DataModel.Custom
{
    public interface IRepository<T>

    {
        void Add(T newEntity);
        void Remove(T entity);       
        IQueryable<T> Find(Expression<Func<T, bool>> predicate);
        IQueryable<T> FindAll();        
    }
}

SQLRepository Implementation

namespace EventScheduling.DataModel.Custom
{
    public class SQLRepository<T>:IRepository<T> where T : class

    {
        protected ObjectSet<T> _objectSet;

        public SQLRepository(ObjectContext context)
        {
            _objectSet = context.CreateObjectSet<T>();
        }

        public IQueryable<T> Find(Expression<Func<T, bool>> predicate){

        return _objectSet.Where(predicate);
        }
        public void Add(T newEntity)
        {
         _objectSet.AddObject(newEntity);
        }
        public void Remove(T entity)
        {
        _objectSet.DeleteObject(entity);
        }

        public IQueryable<T> FindAll()
        {
        return _objectSet;
        }    
    }
}

Unit of Work Implementation

namespace EventScheduling.DataModel.Custom
{
    public interface IUnitOfWork
    {
        IRepository<utility_event> utility_event { get; }
        IRepository<event_activity> event_activity { get; }
        IRepository<employee>  employee{ get; }
        IRepository<activity_resource> activity_resource  { get; }
        IRepository<Elmah_Error>  Elmah_Error { get; }
        IRepository< location> location { get; }
        IRepository<location_station> location_station  { get; }
        IRepository<registration_type> registration_type  { get; }
        IRepository< resource> resource  { get; }
        IRepository<shift> shift { get; }
        IRepository<shift_person> shift_person{ get; }
        IRepository<event_type> event_type { get; }
        IRepository<status> status { get; }

        void Commit();
    }
}

SqlUnitOfWork Implementation

namespace EventScheduling.DataModel.Custom
{
    public class SqlUnitOfWork: IUnitOfWork
    {
        readonly ObjectContext _context;
        const String ConnectionStringName = "EventEntities";


        public SqlUnitOfWork()
        {            
            var connectionString = ConfigurationManager.ConnectionStrings[ConnectionStringName].ConnectionString;
            _context = new ObjectContext(connectionString);
            _context.ContextOptions.LazyLoadingEnabled = true;

        }

        public IRepository<utility_event> utility_event
        {
            get {
                if (_utilityEvent == null)
                {
                    _utilityEvent = new SQLRepository<utility_event>(_context);
                }
                return _utilityEvent;
            }
        }

        public IRepository<event_activity> event_activity
        {
            get
            {
                if (_eventActivities == null)
                {
                    _eventActivities = new SQLRepository<event_activity>(_context);
                }
                return _eventActivities;
            }
        }

        public IRepository<employee> employee
        {
            get
            {
                if (_employees == null)
                {
                    _employees = new SQLRepository<employee>(_context);
                }
                return _employees;
            }
        }

        public IRepository<activity_resource> activity_resource
        {
            get
            {
                if (_activityResources == null)
                {
                    _activityResources = new SQLRepository<activity_resource>(_context);
                }
                return _activityResources;
            }
        }

        public IRepository<location> location
        {
            get
            {
                if (_locations == null)
                {
                    _locations = new SQLRepository<location>(_context);
                }
                return _locations;
            }
        }

        public IRepository<location_station> location_station
        {
            get
            {
                if (_locationStations == null)
                {
                    _locationStations = new SQLRepository<location_station>(_context);
                }
                return _locationStations;
            }
        }

        public IRepository<registration_type> registration_type
        {
            get
            {
                if (_registrationTypes == null)
                {
                    _registrationTypes = new SQLRepository<registration_type>(_context);
                }
                return _registrationTypes;
            }
        }
        public IRepository<resource> resource
        {
            get
            {
                if (_resources == null)
                {
                    _resources = new SQLRepository<resource>(_context);
                }
                return _resources;
            }
        }


        public IRepository<shift> shift
        {
            get
            {
                if (_shifts == null)
                {
                    _shifts = new SQLRepository<shift>(_context);
                }
                return _shifts;
            }
        }


        public IRepository<shift_person> shift_person
        {
            get
            {
                if (_shiftPersons == null)
                {
                    _shiftPersons = new SQLRepository<shift_person>(_context);
                }
                return _shiftPersons;
            }
        }

        public IRepository<Elmah_Error> Elmah_Error
        {
            get
            {
                if (_ElmahError == null)
                {
                    _ElmahError = new SQLRepository<Elmah_Error>(_context);
                }
                return _ElmahError;
            }
        }

        public IRepository<event_type> event_type
        {
            get
            {
                if (_eventTypes == null)
                {
                    _eventTypes = new SQLRepository<event_type>(_context);
                }
                return _eventTypes;
            }
        }

        public IRepository<status> status
        {
            get
            {
                if (_status == null)
                {
                    _status = new SQLRepository<status>(_context);
                }
                return _status;
            }
        }

        public void Commit()
        {  
            _context.SaveChanges();
        }

        SQLRepository<utility_event> _utilityEvent = null;
        SQLRepository<event_activity> _eventActivities = null;
        SQLRepository<employee> _employees = null;
        SQLRepository<activity_resource> _activityResources = null;
        SQLRepository<Elmah_Error> _ElmahError = null;
        SQLRepository<location> _locations = null;
        SQLRepository<location_station> _locationStations = null;
        SQLRepository<registration_type> _registrationTypes = null;
        SQLRepository<resource> _resources  = null;
        SQLRepository<shift> _shifts  = null;
        SQLRepository<shift_person> _shiftPersons  = null;
        SQLRepository<event_type> _eventTypes = null;
        SQLRepository<status> _status = null;
    }
}

Controller Edit Implementation

public ActionResult Edit(int id, shift e)
{
    if (!ModelState.IsValid)
    {
        return View(e);
        //return to view
    }
    else
    {
        e.shift_begin = (DateTime)e.shift_date.Value.Add(e.shift_begin.Value.TimeOfDay);
        e.shift_end = (DateTime)e.shift_date.Value.Add(e.shift_end.Value.TimeOfDay);

        _unitOfWork.Commit();
        return RedirectToAction("Details", "EventActivity", new { id = e.activity_id });
    }

}
Peter
  • 14,221
  • 15
  • 70
  • 110
Kmf
  • 3
  • 1
  • 1
    possible duplicate of [how to update an entity in Entity Framework 4 .NET ](http://stackoverflow.com/questions/3594515/how-to-update-an-entity-in-entity-framework-4-net) – Ladislav Mrnka Jan 19 '11 at 22:06
  • EF's context is already an implementation of Unit of Work, btw. – Restuta Jan 19 '11 at 22:11

1 Answers1

0

When you want to update entity in EF you must first Attach entity to ObjectContext instance or instance of related ObjectSet and use ObjectStateManager.ChangeObjectState to set state of entity to EntityState.Modified.

Other possibility is to load entity first from database and merge changes directly into this entity.

Check link in comment for examples or try to use search box. This question is one of the most frequent in EF tag.

Ladislav Mrnka
  • 360,892
  • 59
  • 660
  • 670
  • Why do I need to attach the entity to the objectcontext, isnt EF supposed to keep track of these changes? – Kmf Jan 19 '11 at 22:31
  • @Kmf: And where is EF supposed to keep track of these changes? You are using ASP.NET MVC. The entity is lost when you send response to the client and **new one** is created by default model binder when edit request arrives. Even if you use custom model binder and store entity in session your ObjectContext is probably already closed so no changes can be tracked. – Ladislav Mrnka Jan 19 '11 at 22:47
  • Thanks, that worked. I guess I am just confused on when and why it loses a reference to the context that is should be attached to. – Kmf Jan 19 '11 at 22:52
  • @Kmf: It depends on lifetime of your UnitOfWork / ObjectContext. You should not share them. Use new instance for each request. Web application is detached scenario - you work with entities which lose connection to context or which are created as disconnected and attached to context. – Ladislav Mrnka Jan 19 '11 at 22:56