当我将一个对象添加到数据库并在同一个HTTP请求中从数据库中选择它时,我从EF Code First得到了一些奇怪的行为。
当我检索它时,它将作为对象类型而不是System.Data.Entity.DynamicProxies类型返回,因此延迟加载不起作用。
如果我在下一个HTTP请求中检索相同的对象,则返回类型为System.Data.Entity.DynamicProxies,并且延迟加载正常。
我是否需要对对象或上下文执行某些操作才能返回DynamicProxy?或者这就是EF Code First的工作原理,如果是这样,我该如何解决这个问题呢?
我甚至使用NuGet包中的示例代码重新创建了这个问题。
以下是我用来重新创建问题的代码:
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();
}
当我在AddPost操作中获得post2时,它返回MvcApplication.Models.Post类型,当我在GetPost操作中返回相同的帖子时,它的类型为System.Data.Entity.DynamicProxies.Post。
使用MVC 3工具更新中的默认MVC3应用程序重新创建上述代码我还安装了以下NuGet包:EntityFramework.Sample和EntityFramework.SqlServerCompact。
如果有人可以重新创建问题或者有解决方案,那么我们将非常感激。
答案 0 :(得分:3)
在C#中,如果您调用new Post()
,那么您将获得Post
实例,而不是Post
的代理子类型的实例。要获得代理,您必须调用不同的东西。
您可以致电DbSet<T>.Create
:
var post = blogContext.Posts.Create();
post.PublishDate = DateTime.Now;
答案 1 :(得分:2)
总猜:尝试使用blogContext.Posts.Create()
而不是new Post()
。这样,您的原始对象将由EF创建,而不是裸露的CLR对象。
答案 2 :(得分:2)
你有几个选择......
如果你不介意从上下文中实例化,你可以这样做:
var post = blogContext.Posts.Create();
如果您正在使用存储库,这将无法工作(因为您的上下文可能会被存储库封装)。
如果您最终使用存储库,则一个选项是在附加/保存后显式加载相关实体。 e.g。
// Load the related entity
context.Entry(post).Reference(u => u.Notes).Load();
另一个选项可能是(尚未测试)保存后不使用“查找”。如果您使用find,EF将首先尝试查看上下文。