0

I have a post method in my controller that is not saving changes to my database (SQL express). I am using viewmodels and valueinjector to populate the VM from my model. I have checked and the values in the viewmodel and they have changed, but when I call my service:

fixedAssetService.SaveFixedAsset() 

and bookmark the following in the service interface:

unitOfWork.Commit()

and pull up the quick watch window for unitOfWork, it has the old value.

All my tables have primary keys and I am using code first. The connection string is valid becasue I can get the items, I just can't save them.

My post method:

[HttpPost]
[ValidateAntiForgeryToken]

public ActionResult Edit(FixedAssetViewModel evm)
{
    var fixedAsset = fixedAssetService.GetFixedAsset(evm.FixedAssetId);
    // Use Injector to handle mapping between viewmodel and model
    fixedAsset.InjectFrom(evm);

    try
    {
        if (ModelState.IsValid)
        {
            fixedAssetService.SaveFixedAsset();
            return RedirectToAction("Details", "FixedAsset", new { id = fixedAsset.FixedAssetId });
        }
    }
    catch (DataException)
    {
        //Log the error (add a variable name after DataException)
        ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists, see your system administrator.");
    }
}

My Service:

namespace FixedAssets.Services
{
    public interface IFixedAssetService
    {
        IEnumerable<FixedAsset> GetAll();
        IEnumerable<FixedAsset> FindBy(Expression<Func<FixedAsset, bool>> predicate);
        FixedAsset GetFixedAsset(string id);
        void CreateFixedAsset(FixedAsset fixedAsset);
        void DeleteFixedAsset(string id);
        void SaveFixedAsset();
        bool ValueInUse(Expression<Func<FixedAsset, bool>> predicate);
    }
    public class FixedAssetService : IFixedAssetService
    {
        private readonly IFixedAssetRepository fixedAssetRepository;
        private readonly IUnitOfWork unitOfWork;
        public FixedAssetService(IFixedAssetRepository fixedAssetRepository, IUnitOfWork unitOfWork)
        {
            this.fixedAssetRepository = fixedAssetRepository;
            this.unitOfWork = unitOfWork;
        }
        #region IFixedAssetService Members

        public IEnumerable<FixedAsset> GetAll()
        {
            var fixedAssets = fixedAssetRepository.GetAll();
            return fixedAssets;
        }

        public IEnumerable<FixedAsset> FindBy(Expression<Func<FixedAsset, bool>> predicate)
        {
            IEnumerable<FixedAsset> query = fixedAssetRepository.FindBy(predicate);
            return query;
        }

        public bool ValueInUse(Expression<Func<FixedAsset, bool>> predicate)
        {
            IQueryable<FixedAsset> query = fixedAssetRepository.FindBy(predicate).AsQueryable();
            int count = query.Count();
            return count > 0 ? true : false;
        }

        public FixedAsset GetFixedAsset(string id)
        {
            var fixedAsset = fixedAssetRepository.GetById(id);
            return fixedAsset;
        }

        public void CreateFixedAsset(FixedAsset fixedAsset)
        {
            fixedAssetRepository.Add(fixedAsset);
            SaveFixedAsset();
        }

        public void DeleteFixedAsset(string id)
        {
            var fixedAsset = fixedAssetRepository.GetById(id);
            fixedAssetRepository.Delete(fixedAsset);
            SaveFixedAsset();
        }

        public void SaveFixedAsset()
        {
            unitOfWork.Commit();
        }

        #endregion
    }
}

Edit: One thing I forgot to mention is this app was modeled almost exactly after an existing app that worked fine. Not sure if I have references messed up or what, but the other app uses the same methods only different entities

steveareeno
  • 1,925
  • 5
  • 39
  • 59
  • At a glance, it would seem like the problem is that Entity framework's change tracking doesn't work when it's hidden behind a repository like that. A solution could be to add an Update() method in your repository, where you attach the entity, and set its state to modified. – Tobias Aug 20 '14 at 16:36
  • Thanks, but even my create method is doing the same thing when I use add in my service: fixedAssetRepository.Add(fixedAsset). The fixedasset object is empty even though the view model was not. – steveareeno Aug 20 '14 at 17:43

1 Answers1

0

I found my problem. In the app I used as a model for this one I was using a separate unity class. My database factory registration was like this:

.RegisterType<IDatabaseFactory, DatabaseFactory>(new HttpContextLifetimeManager<IDatabaseFactory>())

Now I am using Microsoft.Practices.Unity and Unity.Mvc4 so I changed the registration to:

container.RegisterType<IDatabaseFactory, DatabaseFactory>();

per the comments in the bootstrapper class. When I changed it to:

container.RegisterType<IDatabaseFactory, DatabaseFactory>(new HierarchicalLifetimeManager());

per the suggestions on this post:

Stackoverflow thread

it finally worked!

Community
  • 1
  • 1
steveareeno
  • 1,925
  • 5
  • 39
  • 59