Нужно ли вставлять контекст Entity Framework в оператор Using? - PullRequest
63 голосов
/ 05 мая 2009

Объект контекста Entity Framework реализует метод Dispose (), который «освобождает ресурсы, используемые контекстом объекта». Что это делает на самом деле? Может ли быть плохим всегда помещать это в оператор using {}? Я видел, как он используется как с оператором using, так и без него.

Я специально собираюсь использовать контекст EF из метода службы WCF, создать контекст, выполнить некоторое linq и вернуть ответ.

РЕДАКТИРОВАТЬ: Кажется, я не единственный, кто задается этим вопросом. Другой вопрос - что на самом деле происходит внутри метода Dispose (). Некоторые говорят, что это закрывает связи, а некоторые статьи говорят, что нет. В чем дело?

Ответы [ 9 ]

33 голосов
/ 05 мая 2009

Если вы создаете контекст, вы должны удалить его позже. Если вы должны использовать оператор using, это зависит от времени жизни контекста.

  1. Если вы создаете контекст в методе и используете его только в этом методе, вам действительно следует использовать оператор using, поскольку он дает вам обработку исключений без какого-либо дополнительного кода.

  2. Если вы используете контекст в течение более длительного периода времени, т. Е. Время жизни не ограничено временем выполнения метода, вы не можете использовать оператор using, и вам придется вызывать Dispose() самостоятельно и позаботься, чтобы ты всегда это называл.

Что Dispose() делает для контекста объекта?

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

5 голосов
/ 11 ноября 2010

Per Progamming Entity Framework : «Вы можете явно утилизировать ObjectContext или подождать, пока сборщик мусора выполнит эту работу».

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

4 голосов
/ 05 мая 2009

Поскольку вы не знаете, когда сборщик мусора располагает элемент, всегда полезно обернуть объекты, реализующие IDisposable, в using-block , если вы знаете, когда с ним покончено. 1003 *

3 голосов
/ 22 апреля 2014

EF5 и до версии

    using { ...
            // connecction open here.

            ...
            context.Blogs.Add(blog); 
            context.SaveChanges();   // query etc now opens and immediately closes 

            ...
            context.Blogs.Add(blog); 
            context.SaveChanges();   // query etc now opens and immediately closes 
   }

EF6 и после версии

 using {
        // connecction open here.

        ...
        context.Blogs.Add(blog); 
        context.SaveChanges(); 

        // The underlying store connection remains open for the next operation  

        ...
        context.Blogs.Add(blog); 
        context.SaveChanges(); 

        // The underlying store connection is still open 

   } // The context is disposed – so now the underlying store connection is closed

Ссылка: http://msdn.microsoft.com/en-us/data/dn456849#open5

1 голос
/ 08 ноября 2013

Я действительно проверил эту вещь для ADO.net и EF v.6 и наблюдал за соединениями в таблице SQL

select * from sys.dm_exec_connections

Методы, которые нужно протестировать, выглядели так:

1) ADO.net с использованием

  using(var Connection = new SqlConnection(conString))
  {
    using (var command = new SqlCommand(queryString, Connection))
    {    
       Connection.Open();
       command.ExecuteNonQueryReader();
       throw new Exception()  // Connections were closed after unit-test had been 
       //finished.  Expected behaviour
     }
  }

2) ADO.net без использования

var Connection = new SqlConnection(conString);
using (var command = new SqlCommand(queryString, Connection))
{
    Connection.Open();
     command.ExecuteNonQueryReader();
    throw new Exception() // Connections were NOT closed after unit-test had been finished

     finished.  I closed them manually via SQL.  Expected behaviour
    }

1) EF с использованием.

 using (var ctx = new TestDBContext())
    {
        ctx.Items.Add(item);
        ctx.SaveChanges();
        throw new Exception() // Connections were closed, as expected.

     }

2) EF без использования

 var ctx = new TestDBContext();             
 ctx.Items.Add(item);
 ctx.SaveChanges();
 throw new Exception() // Connections WERE successfully closed, as NOT expected.

Я не знаю, почему это так, но EF автоматически закрывает соединения. Также все шаблоны репозитория и UnitOfWork, которые используют EF, не используют using. Это очень странно для меня, потому что DBContext - это тип Disposable, но это факт.

Может быть, в Microsoft они сделали что-то новое для обработки?

1 голос
/ 05 мая 2009

Когда вы утилизируете, ObjectContext удаляет другие находящиеся в собственности объекты.

Включая такие вещи, как EntityConnection, который обертывает фактическое соединение с базой данных, то есть обычно SqlConnection.

То есть, если SqlConnection открыт, он будет закрыт при удалении ObjectContext.

1 голос
/ 05 мая 2009

Всегда, если вы создаете экземпляр класса, который реализует IDisposable, тогда вы несете ответственность за вызов Dispose для него. Во всех случаях, кроме одного, это означает с использованием блока .

0 голосов
/ 10 июня 2013

Если Dispose закрывает соединение с БД, называть его плохой идеей. Например, в ADO.NET соединения находятся в пуле соединений и никогда не закрываются до истечения времени ожидания или пула приложений.

0 голосов
/ 27 марта 2013

Я заметил (хотя только в одном приложении), что явное удаление вызывало исключения прерывания потока в mscorlib, которые перехватываются перед кодом приложения, но по крайней мере в моем случае приводят к заметному снижению производительности. Не проводил каких-либо значительных исследований по этому вопросу, но, вероятно, стоит что-то рассмотреть, если вы делаете это. Просто посмотрите вывод DEBUG, чтобы увидеть, получаете ли вы тот же результат.

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