Monthly Archives: April 2011

Accessing ObjectContext Features from EF 4.1 DbContext

 The Entity Framework 4.1 DbContext is a lightweight version of the EF ObjectContext. It’s simpler to work with thanks t a streamlined surface of properties and methods. It may be just what you’ve always been looking for.

But….

Once in a while you might want to use a random method of the ObjectContext that is not available in the DbContext. .

All is not lost. The EF team built a hook in for you so that you can actually get to the ObjectContext from DbContext. It’s not as simple as a propert however, it requires a bit of casting and more.

When I know I will want the occasional benefit of the ObjectContext, I simply create a property in my DbContext class so it’s easier to get to. 

Here’s what it looks like:

 

   public class MyContext: DbContext
    {
        public DbSet<Blog> Blogs { get; set; }
       //other dbsets, ctor etc.

        public ObjectContext ObjectContext()
        {
            return (this as IObjectContextAdapter).ObjectContext;
        }
    }

Now when I have an instance of the DbContext, I can use features of the ObjectContext on the fly:

 db.ObjectContext()…..

 

 

Why can’t I Edit or Delete my Data Service data?

I spent waaaaaay too much time on this problem yesterday and wanted to share the solution, or more accurately, the workaround.

I’m creating an Azure hosted Data Service and to as a consumer, an Azure hosted MVC application.

My app allows users to query, create, edit and delete data.

I have the permission set properly in the data service.  In fact, in desperation I completely opened up the service’s permissions with

config.SetEntitySetAccessRule("*", EntitySetRights.All);

But calling SaveChanges when there was a modification or delete involved always threw an error: Access is Denied and in some situations a 404 page not found.

When you develop Azure apps in Visual Studio, you do so with Visual Studio running as an Admin and the Azure tools use IIS to host the local emulator. I so rarely develop against IIS anymore. I mostly just use the development server (aka cassini) that shows up as localhost with a port number, e.g., localhost:37.

By default IIS locks down calls to POST, MERGE and DELETE  (e.g. update and delete).

It took me a long time to even realize this but Chris Woodruff asked about that.

So I went into IIS and even saw that “All Verbs” was checked in the Handler Mappings and decided that wasn’t the problem.

Eventually I went back and explicitly added PUT, POST,MERGE,DELETE, GET in the verbs list.

But the problem still didn’t go away.

I deployed the app to see if Azure would have the same problem and unfortunately it did.

I did a lot of whining (begging for ideas) on twitter and some email lists and none of the suggestions I got were panning out.

Today I was very fortunate to have Shayne Burgess and Phani Raj from Microsoft take a look at the problem and Phani suggested to use the workaround that the WCF Data Services team created for this exact problem – when POST is being honored (e.g. insert) but PUT, MERGE and DELETE are being rejected by the server.

There is a property on the DataServiceContext called UsePostTunneling.

Setting it to true will essentially trick the request into thinking it’s a POST and then when the request got the server, saying “haha, just kidding it’s a MERGE or DELETE”. (My twisted explanation…Phani’s was more technical.)

This did the trick both locally and on Azure. But it is a workaround and our hope is to eventually discover the root cause of the problem.

Here’s a blog post by Marcelo Lopez Ruis about the property:

http://blogs.msdn.com/b/marcelolr/archive/2008/08/20/post-tunneling-in-ado-net-data-services.aspx

Hopefully my blog post has some search terms that will help others find it who have the same problem. In all of the searching I did, I never came across post tunneling though I do remember seeing something about flipping POST and PUT in a request header but the context was not inline with my problem enough for me to recognize it as a path to the solution.

Code First/Entity Framework 4.1 Videos and Articles on MSDN

Currently, 8 of the 10 videos on Code First and EF 4.1 I have already created for MSDN are online but they are not easy to find.

Three of them are on the msdn.com/data/videos page. The others have not been placed there yet although you can find links to the videos at msdn.com/data/ef and then from the videos to the articles.

Here are direct links to all of the videos and related articles that are currently online.

  1. Building an MVC 3 App with Code First and Entity Framework 4.1  Whitepaper     Video
  2. Building an MVC 3 App with Model First and Entity Framework 4.1 Whitepaper    Video
  3. Building an MVC 3 App with Database First and Entity Framework 4.1   Whitepaper    Video
  4. Code First Data Annotation   video     article
  5. Code First Relationship Fluent API  video   article not online yet
  6. Code First Database Initializers      video   article not online yet
  7. Validation in Code First and DbContext:  video   article  (note 4/15: MSDN’s EF page points to the annotations content, but I found the correct links 🙂 )
  8. Code First: Mapping Fluent API:  video   article not online yet
  9. DBContext Change Tracker API: video & article not online yet
  10. Code First and WCF Data Services: video & article not online yet

Samples?

I have provided C# and VB samples to go with each section. The samples are already online for the first three and are available from the pages with the articles, not the videos.

Monday May 2, 2011: There seems to be a problem with the videos on MSDN’s website. I have contacted MSDN. They are aware of the problem and trying to resolve it. Sorry. I just created the videos and have nothing to do with the hosting. 😉 Will modify this blog post when the problem has been resolved.  All better now! (8pm EST May 2)

MVC 3 and EF 4.1 Code First: Here are my classes, now you do the rest, kthxbai

One of the announcements this morning at MIX11 was the MVC 3 Tools Update.

Phil Haack has a blog post about them here: http://haacked.com/archive/2011/04/12/introducing-asp-net-mvc-3-tools-update.aspx

I’m really happy to see that the newest MVC 3 Tools for Visual Studio embrace Entity Framework 4.1 in a big way, using the newly released EF 4.1 Code First as the default model for drag & drop MVC apps.

You can truly now get away with this scenario.

  1. Create some classes.
  2. Create an MVC 3 project.
  3. Reference the classes.
  4. Create one or more controllers based on those classes.
    The tooling will pull in Entity Framework 4.1, create a DbContext, build the controller, build the views and add the appropriate code into the controllers to interface between the database and the views.
  5. Change the routing from Home to your model in global.asax.
  6. Run the app.
    Running the app will trigger code first to create a database if it does not yet exist.

Result: a working app with full database interaction around the one or more controllers from your domain classes.

It’s not ready to deploy on, say, the Bank of America website, but it’s a pretty darned good start.

Here’s a closer look.

I start with a few classes in their own project, and for simplicity, I’ll just use the Blog & Post classes that I used for the MSDN Code FIrst video series I created.

domainclasses

Then I add in a new MVC 3 project, using all defaults (Internet Application and Razor view engine).

Notice that the template added in a reference to the EF 4.1 assembly (EntityFramework) and the core EF 4.0 assembly (System.Data.Entity).

references

I make a reference to the DomainClasses assembly and then – important step!! – build the solution.

Now for a controller.

Right click on the Controllers folder and from the context menu, choose Add and then Controller.

Check out the new dialog:

addcontroller

Template has a new option (and it’s the default): Controller with read/write actions and views, using Entity Framework.

Now when you add a controller you can get all of the views for free, rather than having to explicitly create them one at a time.

And “using Entity Framework” is a very new twist.

The next two options are why I had to build the solution. I want it to see the classes in my other project. I’ll choose Blog.

And now Data context class – also very new here. I don’t have one so I’ll choose <New Data Context> from the drop down

newdc

which will prompt me to name it

newdc2

which I do:

newdc3

 

newcontroller

 

After clicking add, the templates go to work. I sit back and relax for a moment.

When it’s finished here’s what I have…

newmodelcontroller

 

The template added a new controller class, a new model context and a new set of views for my blog.

The context class inherits from EF 4.1 DbContext and exposes a DbSet of blogs. It also has some notes related to code first’s auto database generation

context

 

The controller is much smarter than the controller’s created by the previous tooling. Rather than simply creating the method signatures, it uses Entity Framework 4.1 code to provide the base interaction for each method. This is because I chose the create controller “using Entity Framework” option. It creates a class level instance of the context named “db” and uses that in the methods. It uses clean DbContext code such as the Find method which searches on the primary key field for the value you pass in. It uses the very nice Entry method to attach an edited Blog and change it’s state to Edited before saving. It uses the Find and Remove to perform a delete. Personally, I mimic the Edit method (Entry.State=Deleted) to save a trip to the database, but this works too.

namespace MVC3BlogTest.Controllers
{ 
    public class BlogController : Controller
    {
        private BlogDomainContext db = new BlogDomainContext();

        public ViewResult Index()
        {
            return View(db.Blogs.ToList());
        }

        public ViewResult Details(int id)
        {
            Blog blog = db.Blogs.Find(id);
            return View(blog);
        }

        public ActionResult Create()
        {
            return View();
        } 

        [HttpPost]
        public ActionResult Create(Blog blog)
        {
            if (ModelState.IsValid)
            {
                db.Blogs.Add(blog);
                db.SaveChanges();
                return RedirectToAction("Index");  
            }

            return View(blog);
        }
        
        public ActionResult Edit(int id)
        {
            Blog blog = db.Blogs.Find(id);
            return View(blog);
        }

        [HttpPost]
        public ActionResult Edit(Blog blog)
        {
            if (ModelState.IsValid)
            {
                db.Entry(blog).State = EntityState.Modified;
                db.SaveChanges();
                return RedirectToAction("Index");
            }
            return View(blog);
        }

        public ActionResult Delete(int id)
        {
            Blog blog = db.Blogs.Find(id);
            return View(blog);
        }

        [HttpPost, ActionName("Delete")]
        public ActionResult DeleteConfirmed(int id)
        {            
            Blog blog = db.Blogs.Find(id);
            db.Blogs.Remove(blog);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        protected override void Dispose(bool disposing)
        {
            db.Dispose();
            base.Dispose(disposing);
        }
    }
}

The views are already built…to defaults.

Since the default model uses code first, it will create a database for me so all I have to do now is run the app – AFTER I change the default route in global.asax from”Home” to “Blog".

 

route

 

and finally : F5 (run the app)

blog1 blog2

 

blog3 blog4

Now I’ll add a new controller for Post with ONE difference. I want my context to manage both Blog and Post classes because they are related. So rather than creating another context, I use the existing context.

postcontroller

This wizard modifies the BlogDomainContext to add in a DbSet for Post classes.

contextwithpost

It doesn’t go back and change the Blog views so that you can navigate from a blog to a post. You’ll have to do that yourself. But the template DOES recognize the reference inside the post class back to blog and uses that in the default views that it generates for example:

post1

post2

post3

 

These templates provide a great starting point for MVC 3 newbies.

There’s a lot of refactoring I’d want to do, however, they are *templates* which means you can modify the template so that it generates things more to your liking. Or wait for someone else to do it. Smile I’m sure you’ll find plenty of great templates that incorporate more advanced patterns and practices available via nuget as soon as people get their hands on this stuff.