2
\$\begingroup\$

I have experience is C#/ASP.NET, and I've done MVC in Ruby On Rails, so I figured making the jump to ASP.NET MVC would be a breeze. Unfortunately, I'm second-guessing my every decision. I'd like some more eyes on this to tell me if my way of doing things is insane.

My main question is around editing an entity.

My GET looks like this:

public ActionResult Edit(int id)
{
    var viewModel = from c in db.centres
                    // some joins are here
                    where c.id == id
                    select new CentreViewModel {
                      CentreId = c.id,
                      CentreName = c.Name,
                      etc...
                    };
    return View( viewModel );
}

And my POST is something like this:

public ActionResult Edit(CentreViewModel viewModel)
{
    // NOTE - Validation & Error handling exists, but has been omitted for berevity
    var centre = db.centres.First(c => c.id == viewModel.CentreId);
    centre = Mapper.Map<CentreViewModel, CentreEntity>(viewModel, centre);

    db.centres.ApplyCurrentValues( centre );
    db.SaveChanges();
}

Is this kinda-sorta right? Are there any red flags here? Is ApplyCurrentValues correct? I see others using repository.Entry(), but I don't have a repository for my classes, near as I can tell...

\$\endgroup\$
  • 1
    \$\begingroup\$ Not enough expirience with EF to answer your question (which DOES look right btw) but I generally disparage people away from the from...where...select LINQ syntax as it hides what's actually going on in a very unhelpful way. Since LINQ has been out, in 100% of the scenarios that I've seen that using the expression syntax is more powerful, terse, and more likely to convey to developers what's really happening. In your case you should be able to shorten the actual query to db.centres.First(x=>x.id == id).. though it is missing the projection part which you have to do separately in code. \$\endgroup\$ – George Mauer Mar 2 '12 at 17:39
  • \$\begingroup\$ The reason I went with the LINQ syntax is because the joins don't have foreign keys and, based on about 30 seconds of googling, this was the easiest way to join on tables without FKs. I'll take another look, see if I can improve it. \$\endgroup\$ – Matt Grande Mar 2 '12 at 18:28
  • 1
    \$\begingroup\$ Well both are technically LINQ syntax. There is nothing that you can do with query syntax that you can't do with lambda syntax. There is a lot you can do with lambda syntax that you can't the other way around though. \$\endgroup\$ – George Mauer Mar 2 '12 at 21:58
2
\$\begingroup\$

Here is a link to the "official" tutorial on basic CRUD operations in ASP.NET MVC and EF.

The main difference is the validation checking, and the exception handling. I recommend adding in the validation, and possibly the exception handling if you need it. Don't randomly swallow exceptions and show the user some generic error message.

Other than that, they use a slightly different way of letting EF know about the entity to be updated, but I think they're accomplishing the same thing. I think the functional difference is that you are only posting back the necessary data to be updated, and having EF get the entity and update it with those changes for you. With their method, I think that they are posting back the entire entity, and having EF "reattach" the entity and mark it as modified.

So I think the differences in the update code boil down to partial vs. full entity updates.

Side Note 1

I like your way better. In their case they are relying on the end user to postback the entire entity. While that is a basic demo, using this method blindly opens up your application to vulnerabilities where people can update any field they want, even if the field doesn't appear in the HTML form (Think of an "IsAdmin" flag). I believe that this is known as a Mass Assignment vulnerability that bit Rails and Github last week! (Source: https://github.com/blog/1068-public-key-security-vulnerability-and-mitigation)

Side Note 2

About the comments and the LINQ syntax... I also like the expression syntax a little more, at least for short, small queries. But when doing joins in the past, I've gone with the query syntax. Just a personal preference. Here is what the code would look like with the LINQ expression syntax (as opposed to the query syntax):

db.centres
    .Join(...)
    .Where(c => c.id == id)
    .Select(new CentreViewModel
        {
            CentreId = c.id,
            CentreName = c.Name,
            etc...
        };
\$\endgroup\$
  • \$\begingroup\$ That's weird, I don't have that Entry method they're using. Ah well, no one's told me that I'm completely out to lunch, so I think my way of doing it is Good Enough™. \$\endgroup\$ – Matt Grande Mar 8 '12 at 15:57
  • 1
    \$\begingroup\$ I think they have a simplified DbContext class now. I would check it out since it's supposed to make things a bit cleaner. You should be able to update to the latest EF version through Nuget. \$\endgroup\$ – John Bubriski Mar 8 '12 at 16:12
1
\$\begingroup\$

I usually use generics to handle my database contexts. Here is an example of how I would approach it explicitly.

        db.centres.Attach(centre);
        db.Entry(centre).State = EntityState.Modified;
        db.SaveChanges();

Moreover, here is a link to one of the best tutorials out there in my opinion for mvc3.

http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/creating-an-entity-framework-data-model-for-an-asp-net-mvc-application (Make sure to note that there are 10 different parts, the link to the next step is at the bottom of the page).

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.