Подтвердить что ты не робот

Entity Framework. Как я могу указать экземпляр объекта "Объекты"

Я полный новичок в Entity Framework и ASP.Net MVC, узнав в основном из учебников, не имея глубокого понимания. (У меня есть опыт работы с .Net 2.0, ADO.Net и WebForms)

Мое настоящее сомнение возникает из-за того, что я инстинкт объектов Entities.

В основном я делаю это в своих контроллерах:

public class PostsController : Controller {

    private NorthWindEntities db = new NorthWindEntities();

    public ActionResult Index() {
            // Use the db object here, never explicitly Close/Dispose it
    }
}

Я делаю это так, потому что я нашел его в каком-то блоге MSDN, который казался мне достаточно авторитетным, и я предположил, что это правильный путь.
Тем не менее, я чувствую себя довольно непростым. Хотя это сэкономит мне много кода, я привык делать:

using (NorthWindEntities db = new NorthWindEntities() {
}

В каждом отдельном методе, который нуждается в соединении, и если этот метод вызывает другие, которые ему понадобятся, он передаст им db в качестве параметра. Вот как я сделал все с моими объектами подключения до того, как существовал Linq-to-SQL.

Другое, что заставляет меня беспокоиться, это то, что NorthWindEntities реализует IDisposable, что по соглашению означает, что я должен называть его методом Dispose(), а я нет.

Что вы думаете об этом?
Правильно ли это экземпляр объекта Entities, как я это делаю? Должен ли он заботиться о своих связях, открывая и закрывая их для каждого запроса?
Или я должен явно распоряжаться им предложением use()?

Спасибо!

4b9b3361

Ответ 1

Сам контроллер реализует IDisposable. Таким образом, вы можете переопределить Dispose и избавиться от чего-либо (например, контекста объекта), который вы инициализируете при создании экземпляра контроллера.

Контроллер работает только в течение одного запроса. Таким образом, использование внутри действия и наличие одного контекста объекта для всего контроллера - это точно такое же количество контекстов: 1.

Большая разница между этими двумя методами заключается в том, что действие будет выполнено до отображения представления. Поэтому, если вы создадите ObjectContext в операторе using внутри действия, ObjectContext будет удален до представления представления. Поэтому вам лучше прочитать что-либо из контекста, который вам нужен, прежде чем действие завершится. Если модель, которую вы передаете в представление, представляет собой некоторый ленивый список, такой как IQueryable, вы должны использовать контекст перед визуализацией представления, вызывая исключение, когда представление пытается перечислить IQueryable.

В отличие от этого, если вы инициализируете ObjectContext, когда контроллер инициализируется (или пишет ленивый код инициализации, вызывающий его инициализацию при выполнении действия) и удаляет ObjectContext в Controller.Dispose, тогда контекст будет по-прежнему вокруг, когда визуализируется представление. В этом случае безопасно передать IQueryable в представление. Контроллер будет удален сразу после отображения представления.

Наконец, я был бы упущен, если бы не заметил, что, вероятно, это плохая идея, чтобы ваш контроллер знал о Entity Framework вообще. Посмотрите на использование отдельной сборки для вашей модели и шаблона репозитория, чтобы контроллер разговаривал с моделью. Поиск в Google будет довольно немного по этому поводу.

Ответ 2

Вы делаете здесь хороший момент. Как долго должен жить объект ObjectContext? Все шаблоны и книги практики (например, Dino Esposito Microsoft-NET-Architecting-Applications) скажу вам, что DataContext не должен долго жить и не должен кэшироваться.

Мне просто интересно, почему в вашем случае нет класса ControllerBase (я не знаю о реализации MVC, так что несите меня), где ObjectContext запускается один раз для всех контроллеров. Особенно подумайте о схеме карты идентичности, который уже реализован Entity Framework. Несмотря на то, что вам нужно вызвать другого контроллера в качестве вашего PostsController, он все равно будет работать с тем же Контекстом и улучшит производительность.