Должен ли контекст Framework Entity использовать в использовании Statement?

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

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

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

Ответ 1

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

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

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

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

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

Ответ 2

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

Ответ 3

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

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

Ответ 4

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

Ответ 5

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

Ответ 6

При размещении объекта ObjectContext располагаются другие принадлежащие ему объекты.

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

Итак, если 'SqlConnection открыт, он будет закрыт, когда вы разместите ObjectContext.

Ответ 7

Я действительно проверил эту вещь как для 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, не используют использование. Это очень странно для меня, потому что DBContext - это одноразовый тип, но это факт.

Возможно, в Microsoft они сделали что-то новое для обработки?

Ответ 8

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

Ответ 9

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