samantha07
samantha07

Reputation: 507

EF won't detect changes

I'm using a generic repository and a unit of work, don't know why it won't detect the changes I made to the database.

public abstract class Repository<T> : IRepository<T>
    where T : class, IAuditEntity
{
    protected IObjectSet<T> _objectSet;

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

    #region IRepository<T> Members

    public abstract T GetById(object id);

    public IEnumerable<T> GetAll()
    {
        return _objectSet.Where(e => !e.IsDeleted).OrderByDescending(o => o.ModifiedOn);
    }

    public IEnumerable<T> Query(Expression<Func<T, bool>> filter)
    {
        return _objectSet.Where(filter);
    }

    public void Add(T entity)
    {
        _objectSet.AddObject(entity);
    }

    public void Update(T entity)
    {
       //some code here; not working
       //What do I need to put here?
    }

    public void Remove(T entity)
    {
        _objectSet.DeleteObject(entity);
    }
}

Controller:

[HttpPost]
    public ActionResult Edit(Student stud)
    {
        if (ModelState.IsValid)
        {
            _unitOfWork.Students.Update(stud);
            _unitOfWork.Commit();
            return RedirectToAction("Index");
        }
        return View(stud);
    }

Before, I try to update my record using this:

[HttpPost]
    public ActionResult Edit(Student stud)
    {
        if (ModelState.IsValid)
        {
            var i = _unitOfWork.Students.GetById(stud.StudentID);
            TryUpdateModel(i);
            _unitOfWork.Commit();
            return RedirectToAction("Index");
        }
        return View(stud);
    }

Sure it works, but I am certain that this is not the proper way to do it. Just want to ask what do I need to make the Update method on my repository work?

Upvotes: 3

Views: 1060

Answers (2)

Gavin
Gavin

Reputation: 17402

This is happening because when the Student object gets posted back to the controller it is no longer attached to the entity framework context due to the stateless nature of HTTP.

Your second approach of getting the record from the DB and modifying it is fine but obviously involves an extra round trip to the database.

I normally use Dbcontext rather than ObjectContext which I belive is essentially a wrapper around ObjectContext with some extra functionality. I'm not sure if this helps or not but if you were to use DbContext you would be able to do this....

dbContext.Entry(stud).State = EntityState.Modified;
dbContext.SaveChanges();

The same can be achieved through the ObjectContext by calling AttachTo to re-attach the returned Student back to the context and then set it's state to modified before you call SaveChanges.

Upvotes: 1

Ladislav Mrnka
Ladislav Mrnka

Reputation: 364409

You need to keep reference to the context in your repository and use this:

public void Update(T entity)
{
   _objectSet.Attach(entity);
   _context.ObjectStateManager.ChangeObjectState(entity, EntityState.Modified);
}

Upvotes: 3

Related Questions