I’m getting some strange behaviour from EF Code First when I add an object to the database and select it back from the database in the same HTTP request.
When I retrieve it, it is returned as the object type rather than of type System.Data.Entity.DynamicProxies so the lazy loading doesn’t work.
If I retrieve the same object in the next HTTP Request then it is return as type System.Data.Entity.DynamicProxies and the lazy loading works fine.
Do I need to do something to the object or the context to get a DynamicProxy returned? Or is this how EF Code First is meant to work, if so how do I get around this issue?
I’ve even recreated the problem using the sample code in the NuGet packages.
Here’s the code that I used to recreate the problem:
public ActionResult Index() {
var blogContext = new BlogContext();
var posts = blogContext.Posts;
ViewBag.Message = "Welcome to ASP.NET MVC!";
ViewBag.Posts = posts;
return View();
}
public ActionResult AddPost() {
var blogContext = new BlogContext();
var post = new Post() {
PublishDate = DateTime.Now,
Text = "Text",
Title = "Title",
};
blogContext.Posts.Add( post );
blogContext.SaveChanges();
var post2 = blogContext.Posts.Find( post.ID );
return RedirectToAction( "Index" );
}
public ActionResult GetPost(int id) {
var blogContext = new BlogContext();
var post = blogContext.Posts.Find( id );
ViewBag.Post = post;
return View();
}
When I get post2 in the AddPost action it is return of type MvcApplication.Models.Post where as when I return the same post in the GetPost action it is of type System.Data.Entity.DynamicProxies.Post.
The above code was recreated using the default MVC3 Application from the MVC 3 Tools Update I also installed the following NuGet packages: EntityFramework.Sample and EntityFramework.SqlServerCompact.
If anyone can recreate the problem or has a solution for this then it would be greatly appreciated.
In C#, if you call
new Post(), then you’re going to get aPostinstance, not an instance of a proxy subtype ofPost. To get a proxy, you have to call something different.You can, e.g., call
DbSet<T>.Create: