Steve Giordano
Steve Giordano

Reputation: 133

MVC Controller Post Method with ViewModel to Update EF Entities

After a bunch of reading on best practices I am now using a viewmodel which is customized for every view and my controller methods pass the viewmodels to the view and then update the db.

I have my GET methods working properly using LINQ projection but I'm not sure what to do in the POST method. If my viewmodel only contains the properties that its view is updating, but an entry already exists in the database for that particlar key, how to I update my EF model with the viewmodel properties without having the get every property in the EF model every time?

Here is my code:

ViewModel

public class GeneralViewModel
{
    public string Title { get; set; }
    public decimal? Proposal_Type_ID { get; set; }
    public string User_Facility_ID { get; set; }
    public IEnumerable<SelectListItem> ProposalTypes { get; set; }
}

Controller

    public ActionResult General(int id)
    {
        var context = new PASSEntities();

        var model = (from a in context.Proposals
                     where a.ID == id
                     select new GeneralViewModel()
                     {
                         User_Facility_ID = a.User_Facility_ID,
                         Title = a.Title,
                         Proposal_Type_ID = a.Proposal_Type_ID
                     }).SingleOrDefault();

        var proposalTypes = context.Proposal_Types.Where(m => m.User_Facility_ID == model.User_Facility_ID).ToList();
        model.ProposalTypes = proposalTypes.Select(m => new SelectListItem { Value = m.ID.ToString(), Text = m.Description }).ToList();

        return PartialView(model);
    }


    [HttpPost]
    public ActionResult General(int id, GeneralViewModel model)
    {
        try
        {
            var context = new PASSEntities();
            var proposal = context.Proposals.Find(id);

            proposal.Title = model.Title;
            proposal.Proposal_Type_ID = model.Proposal_Type_ID;

            context.Entry(proposal).State = System.Data.EntityState.Modified;
            context.SaveChanges();

            return PartialView();
        }
        catch
        {
            return View();
        }

    }

My Post method is working but I don't feel like this is the best way to do it. The reason I did it this way was when I just newed up an EF Proposal model and mapped it's properties to the viewmodel properties, it changed my User_Facility_ID value to null because I didn't used it in my form.

So really I'm just looking for the best way to perform the POST.

Upvotes: 4

Views: 2998

Answers (1)

Maess
Maess

Reputation: 4146

What you are doing is the 'correct' method, you need to get your entity from the context, make the updates and then save the changes.

When you are using a mapping tool like AutoMapper, make sure that you exclude key fields that you do not want updated from the the map.

Upvotes: 2

Related Questions