Повторно используемый ObjectContext или новый ObjectContext для каждого набора операций? - PullRequest
3 голосов
/ 09 августа 2009

Я новичок в Entity Framework и только начинаю играть с ним в свободное время. Один из основных вопросов, которые у меня есть, касается того, как обращаться с ObjectContexts.

Что обычно является предпочтительным / рекомендуемым из них:

Это

public class DataAccess{

    MyDbContext m_Context;

    public DataAccess(){
        m_Context = new MyDbContext();        
    }

    public IEnumerable<SomeItem> GetSomeItems(){
        return m_Context.SomeItems;
    }

    public void DeleteSomeItem(SomeItem item){
        m_Context.DeleteObject(item);
        m_Context.SaveChanges();
    }
}

Или это?

public class DataAccess{

    public DataAccess(){ }

    public IEnumerable<SomeItem> GetSomeItems(){
        MyDbContext context = new DbContext();
        return context.SomeItems;
    }

    public void DeleteSomeItem(SomeItem item){
        MyDbContext context = new DbContext();
        context.DeleteObject(item);
        context.SaveChanges();
    }
}

Ответы [ 4 ]

6 голосов
/ 19 августа 2009

ObjectContext предназначен для "единицы работы".

По сути, это означает, что для каждой «Операции» (например, для каждого запроса веб-страницы) должен быть новый экземпляр ObjectContext. В рамках этой операции один и тот же ObjectContext должен использоваться повторно.

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

Если вы не пишете веб-приложение и вместо этого пишете приложение WPF или Windows Form, оно становится немного более сложным, так как у вас нет узкой области действия «запроса», как у веб-страницы. нагрузка дает вам, но вы поняли.

PS: В любом из ваших примеров время жизни ObjectContext будет либо глобальным, либо временным. В обеих ситуациях он НЕ должен находиться внутри класса DataAccess - он должен передаваться как зависимость

1 голос
/ 17 августа 2009

Если вы сохраняете тот же контекст для длительного процесса, выполняющего много запросов против него, linq-to-sql (я не проверял linq для сущностей, но Я думаю, что это та же проблема) становится ОЧЕНЬ медленным (1 запрос в секунду после примерно 1000 простых запросов). Регулярное обновление контекста решает эту проблему и стоит недорого.

Что происходит, так это то, что контекст отслеживает каждый запрос, который вы выполняете, поэтому, если он не сбрасывается каким-либо образом, он становится действительно толстым ... Другая проблема - это занимаемая память.

Таким образом, это в основном зависит от того, как работает ваше приложение, и от того, регулярно ли вы обновляете экземпляр DataAccess или сохраняете его неизменным. Надеюсь, это поможет.

Stéphane

0 голосов
/ 19 августа 2009

Хотя я не сторонник того, чтобы создавать сложные объекты каждый раз, когда они мне нужны, я также обнаружил, что DataContexts в Linq to Sql и ObjectContexts в EF лучше всего создаются при необходимости.

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

Самым большим препятствием, с которым вы сталкиваетесь, является тот факт, что как только вы получаете сущность из контекста, вы не можете просто передать ее обратно в другую для выполнения операций обновления или добавить связанные сущности обратно. В EF вы можете повторно присоединить сущность обратно в новый контекст. В L2S этот процесс почти невозможен.

0 голосов
/ 11 августа 2009

Просто краткое замечание - две части кода примерно одинаковы в своей основной проблеме. Это то, на что я обращаю внимание, потому что вы не хотите продолжать открывать и закрывать контекст (см. Второй пример), в то же время вы не уверены, что вы можете доверять Microsoft, чтобы правильно распоряжаться контекстом для вас.

Одной из вещей, которые я сделал, было создание общего базового класса, который лениво загружает Контекст и реализует деструктор базового класса для избавления от вещей. Это хорошо работает для чего-то вроде инфраструктуры MVC, но, к сожалению, приводит к проблеме необходимости передачи контекста различным уровням, чтобы бизнес-объекты могли совместно использовать вызов.

В конце концов я использовал что-то, используя Ninject, чтобы внедрить эту зависимость в каждый слой, и проследил за использованием

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