Entity Framework ObjectContext для повторного использования - PullRequest
13 голосов
/ 27 апреля 2010

Я сейчас изучаю EF и у меня есть вопрос относительно ObjectContext:

Должен ли я создавать экземпляр ObjectContext для каждого запроса (функции) при доступе к базе данных?

Или лучше создать его один раз (синглтон) и использовать повторно?

До EF я использовал блок доступа к данным корпоративной библиотеки и создал экземпляр доступа к данным для функции DataAccess ...

Ответы [ 6 ]

15 голосов
/ 27 апреля 2010

Я думаю, что наиболее распространенный способ - использовать его для каждого запроса. Создайте его в начале, делайте то, что вам нужно (большую часть времени это операции, требующие общего ObjectContext), располагайте в конце. Большинство платформ DI поддерживают этот сценарий, но вы также можете использовать HttpModule для создания контекста и помещения его в HttpContext.Current.Items. Это простой пример:

public class MyEntitiesHttpModule : IHttpModule
{
    public void Init(HttpApplication application)
    {
        application.BeginRequest += ApplicationBeginRequest;
        application.EndRequest += ApplicationEndRequest;
    }

    private void ApplicationEndRequest(object sender, EventArgs e)
    {
        if (HttpContext.Current.Items[@"MyEntities"] != null)
            ((MyEntities)HttpContext.Current.Items[@"MyEntities"]).Dispose();
    }

    private static void ApplicationBeginRequest(Object source, EventArgs e)
    {
        var context = new MyEntities();
        HttpContext.Current.Items[@"MyEntities"] = context;
    }
}
14 голосов
/ 27 апреля 2010

Определенно для каждого запроса. Это легкий объект, поэтому не нужно тратить много времени на его создание каждый раз, когда он вам нужен.

Кроме того, чем дольше вы сохраняете ObjectContext живым, тем больше кэшируемых объектов он будет содержать при выполнении запросов к нему. Это может вызвать проблемы с памятью. Поэтому иметь ObjectContext в качестве синглтона - это особенно плохая идея. По мере того как ваше приложение используется, вы загружаете все больше и больше объектов в одноэлементный ObjectContext, пока, наконец, у вас не появится вся база данных в памяти (если только вы не отсоединяете объекты, когда они вам больше не нужны).

А потом возникает проблема с ремонтопригодностью. Однажды вы пытаетесь отследить ошибку, но не можете определить, куда были загружены данные, которые ее вызвали.

1 голос
/ 28 апреля 2010

Как говорит Люк, этот вопрос задавали много раз на SO.

Для веб-приложения лучше всего подходит цикл обработки запросов. Синглтон определенно плохая идея.

Для каждого запроса хорошо работает, потому что на одной веб-странице есть Пользователь, возможно, некоторые Проекты, принадлежащие этому пользователю, может быть несколько Сообщений для этого пользователя. Вам нужен тот же ObjectContext, чтобы вы могли перейти к User.Messages, чтобы получить их, возможно, пометить некоторые сообщения как прочитанные, возможно добавить проект, а затем либо зафиксировать, либо отказаться от всего графа объектов по завершении цикла страницы.

1 голос
/ 27 апреля 2010

Не используйте синглтон ... каждый, кто использует ваше приложение, поделится этим, и всякие безумные вещи произойдут, когда этот объектный контекст отслеживает сущности.

Я бы добавил это как приватный член

0 голосов
/ 21 августа 2011
public class DBModel {

        private const string _PREFIX = "ObjectContext";

        // DBModel.GetInstance<EntityObject>();
        public static ObjectContext GetInstance<T>() {
            var key = CreateKey<T>();
            HttpContext.Current.Items[key] = HttpContext.Current.Items[key] ?? Activator.CreateInstance<T>();
            return HttpContext.Current.Items[key] as ObjectContext;
        }

        private static string CreateKey<T>() {
            return string.Format("{0}_{1}", _PREFIX, typeof(T).Name);
        }
    }
0 голосов
/ 27 января 2011

Позднее сообщение здесь на 7 месяцев. В настоящее время я занимаюсь этим вопросом в своем приложении и склоняюсь к решению @LukLed, создавая одноэлементный ObjectContext на время моего запроса HttpRequest. Для моей архитектуры у меня есть несколько элементов управления, которые используются при создании страницы, и все эти элементы управления имеют свои собственные проблемы с данными, которые извлекают данные только для чтения из уровня EF. Это кажется расточительным для каждого, кто создает и использует свой собственный ObjectContext. Кроме того, есть несколько ситуаций, когда один элемент управления может перетаскивать данные в контекст, которые могут быть повторно использованы другими элементами управления. Например, на моей главной странице мой заголовок вверху страницы содержит информацию о пользователе, которую могут использовать другие элементы управления на странице.

Меня беспокоит только то, что я могу перетянуть сущности в контекст, который повлияет на запросы других элементов управления. Я этого еще не видел, но не знаю, спрашиваю ли я о неприятностях. Я думаю, мы увидим!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...