2009-08-09 7 views
3

Я новичок в Entities Framework, и я только начинаю играть с ним в свободное время. Один из основных вопросов, который у меня есть, - это то, как обращаться с ObjectContexts.Повторный объект ObjectContext или новый ObjectContext для каждого набора операций?

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

Этот

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(); 
    } 
} 
+0

Немного связано с http://stackoverflow.com/questions/1072391/with-linq-do-you-create-a-single-dbcontext-per-request-like-nhibernate-requires – shahkalpesh

+0

И это ... http : //stackoverflow.com/questions/226127/ Хотя обсуждение Linq2Sql, то же самое относится. – spender

ответ

6

ObjectContext предназначается, чтобы быть "Единица работы".

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

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

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

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

0

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

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

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

+0

Microsoft рекомендует не иметь длительные DataContexts или ObjectContexts. Он убивает производительность и усложняет отслеживание объектов. –

1

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

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

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

Stéphane

0

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

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

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

+0

в результате этого - я всегда просто использую заявление вокруг моего документа datacontext/objectcontext и нажимаю на него все манипуляции с данными; Мои контексты всегда максимально коротки. –