EF代码首先不将对象作为DynamicProxies返回,直到HTTP请求完成

时间:2011-06-02 20:32:28

标签: asp.net-mvc entity-framework asp.net-mvc-3 ef-code-first code-first

当我将一个对象添加到数据库并在同一个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。

如果有人可以重新创建问题或者有解决方案,那么我们将非常感激。

3 个答案:

答案 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将首先尝试查看上下文。