EF Code Сначала не возвращать объект как DynamicProxies до тех пор, пока не завершится HTTP-запрос - PullRequest
1 голос
/ 03 июня 2011

Я получаю странное поведение из кода EF Сначала, когда я добавляю объект в базу данных и выбираю его из базы данных в том же HTTP-запросе.

Когда я получаю его, он возвращается как тип объекта, а не как тип 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();
}

Когда я получаю post2 в действии AddPost, оно возвращает тип MvcApplication.Models.Post, где, когда я возвращаю тот же пост в действии GetPost, он имеет тип System.Data.Entity.DynamicProxies.Post.

Приведенный выше код был воссоздан с использованием приложения MVC3 по умолчанию из обновления MVC 3 Tools. Я также установил следующие пакеты NuGet: EntityFramework.Sample и EntityFramework.SqlServerCompact.

Если кто-то сможет воссоздать проблему или найдет решение, тогда это будет очень признательно.

Ответы [ 3 ]

3 голосов
/ 03 июня 2011

В C #, если вы позвоните new Post(), вы получите экземпляр Post, а не экземпляр подтипа прокси Post. Чтобы получить прокси, вам нужно позвонить по-другому.

Вы можете, например, позвонить DbSet<T>.Create:

var post = blogContext.Posts.Create();
post.PublishDate = DateTime.Now;
2 голосов
/ 03 июня 2011

У вас есть несколько вариантов ...

Если вы не возражаете против создания экземпляра из контекста, вы можете сделать:

var post = blogContext.Posts.Create();

Это не будет работать так же хорошо, если выработают с репозиторием (поскольку ваш контекст, вероятно, будет инкапсулирован репозиторием).

Если вы в конечном итоге используете репозиторий, одним из вариантов является явная загрузка связанных объектов после присоединения / сохранения.Например,

// Load the related entity
context.Entry(post).Reference(u => u.Notes).Load();

Еще один вариант (не проверенный) - не использовать Поиск после сохранения.Если вы используете find, EF сначала попытается посмотреть в контексте.

2 голосов
/ 03 июня 2011

Общее предположение: попробуйте и используйте blogContext.Posts.Create() вместо new Post(). Таким образом, ваш оригинальный объект будет создан EF, а не голым объектом CLR.

...