1

How do you mix the concepts of ASP.NET MVC and entityframework in a elegant and robust way when it comes to retrieving stuff from the database and visualizing it via the controller and view?

The example below will throw Dispose exceptions because the View will be displayed after the using statement is closed.

        // code in controller
        using (var usersDb = new UsersDb(new WebSecurityWrapper()))
        {
            var user = usersDb.GetUser(User.Identity.Name);
            return View(user);
        }

        // code in usersDb model -- GetUser method
        public User GetUser(string name)
        {
            var id = _webSecurity.GetUserId(name);
            var user = Users.FirstOrDefault(usr => usr.Id == id);

            return user;
        }

Pretty obvious, but the only alternative I can think of is "cloning" the user object so that the View can display it independently. That doesn't feel right.

So what's the appropriate way of doing this?

bas
  • 11,697
  • 16
  • 53
  • 116
  • Assign `user` outside of the using then? Heres a good tutorial about databases mvc: http://www.asp.net/mvc/tutorials/older-versions/movie-database/create-a-movie-database-application-in-15-minutes-with-asp-net-mvc-cs – Nate-Wilkins Jan 01 '13 at 16:13
  • Could you show usersDb.GetUser() method body? – Kirill Bestemyanov Jan 01 '13 at 16:24
  • Hi Kirill I updated the question with the implementation of GetUser. – bas Jan 01 '13 at 16:40
  • Hi Nate, I think you mean "declare user outside the using"? That doesn't work either since I access the user variable outside the scope of the using. The solution that your tutorial provides is indeed not using a using statement. That works. But is that the way to go? Because now the object will get disposed whenever the garbage collector decides when to finalize the usersDb object which ran out of scope when the controller method is executed. That doesn't seem a healthy solution or am I misunderstanding some things here? – bas Jan 01 '13 at 16:44
  • Have you tried your return View statement outside the scope of the using? – Greg Smith Jan 01 '13 at 16:46
  • yup I ended up with the exact same as you answered below. – bas Jan 01 '13 at 17:25

2 Answers2

1

I think you are using navigation properties of the User object in the view. These are probably evaluated in a lazy way.

The User object is created before you exit the method. Somehow you are requesting extra info which is queried in the view. But since the dispose already happended, this results in the exception.

One option is to use Include to immediately query the extra necessary data.

Community
  • 1
  • 1
Maarten
  • 21,254
  • 3
  • 44
  • 62
0
    User user;
    using (var usersDb = new UsersDb(new WebSecurityWrapper()))
    {
        user = usersDb.GetUser(User.Identity.Name);
    }

    return View(user);
Greg Smith
  • 2,379
  • 2
  • 22
  • 36
  • Hi Greg, thx for the suggestion but that results in the exact same problem since the user object is used outside the scope of the using statement (namely, in the View). Removing the using statement works, but as I mentioned in a comment above that feels kinda tricky since the dispose method will be called whenever the garbage collector decides to finalize the usersDb object. – bas Jan 01 '13 at 16:49
  • 1
    Ok, have you thought about using a repository and unit of work style pattern - this is a pretty effective and easy to achieve setup, it's also very widely used, documented nicely here: http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application – Greg Smith Jan 01 '13 at 16:53
  • reading through it right now. Great link! Will reply when done reading. Also a link to TDD with MVC/EF (!!). – bas Jan 01 '13 at 17:29
  • Awesome material! I'll adjust the design to their repository and unit of work pattern. Many thx for the link! PS: Maarten just gave the answer that solves my problem. I had to include something in the query. – bas Jan 01 '13 at 18:35