Jon Gallant: Do I always have to call Dispose() on my DbContext objects? Nope

The default behavior of DbContext is that the underlying connection is automatically opened any time is needed and closed when it is no longer needed. E.g. when you execute a query and iterate over query results using “foreach”, the call to IEnumerable<T>.GetEnumerator() will cause the connection to be opened, and when later there are no more results available, “foreach” will take care of calling Dispose on the enumerator, which will close the connection. In a similar way, a call to DbContext.SaveChanges() will open the connection before sending changes to the database and will close it before returning.

Given this default behavior, in many real-world cases it is harmless to leave the context without disposing it and just rely on garbage collection.

這是一位來自微軟EF資深研發工程師Diego Vega的回應,他說EF下的DbConnection會隨著存取資料自動開啟DB連線,也會隨著Dispose()明確地關閉連線。雖然EF的GC資源回收機制也會呼叫其Dispose()函式來關閉DB連線,但觸發時機不一定,所以他建議明確呼叫DbContext.Dispose()來關閉DB連線是比較好的方式,這也是為何EF的Sample Code總是用using()的主因。

換句話說,若你的DB Helper Class是吃EF底下的DbConnection物件,其一開始ConnectionState是Closed關閉的,因此記得判斷一下State開啟它,並在最後呼叫DbContext.Dispose()來明確關閉DbConnection。

No comments: