Должен ли контекст Entity Framework быть помещен в Оператор Using?



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



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



EDIT: кажется, что Я не единственный, кому это интересно. Другой вопрос, что на самом деле происходит внутри метода Dispose (). Некоторые говорят, что он закрывает соединения, а некоторые статьи говорят, что нет. В чем дело?

526   9  

9 ответов:

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

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

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

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

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

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

на Progamming Сущности Рамок: "вы можете либо явно удалить ObjectContext, либо дождаться, пока сборщик мусора выполнит эту работу."

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

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

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

когда вы размещаете, ObjectContext размещает другие принадлежащие объекты.

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

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

Я действительно проверил эту вещь для обоих 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 withour с помощью

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

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

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

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

Comments

    Ничего не найдено.