Entity Framework - Как мне создать экземпляр моего объекта "Entities" - PullRequest
18 голосов
/ 09 сентября 2009

Я абсолютный новичок в 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, как я делаю? Должен ли он заботиться о своих соединениях, открывая и закрывая их для каждого запроса?
Или я должен явно избавиться от него с помощью оператора using ()?

Спасибо!

Ответы [ 2 ]

22 голосов
/ 09 сентября 2009

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

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

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

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

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

3 голосов
/ 30 декабря 2009

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

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

...