If you talk about dynamic proxies in EF there are two different types to distinguish:
- Proxies for lazy loading
- Proxies for change tracking
Usually a change tracking proxy also can serve as a proxy for lazy loading. The reverse is not true. This is because the requirements for change tracking proxies are higher, especially all properties - also the scalar properties - must be virtual
. For lazy loading it is enough that the navigation properties are virtual
.
The fact that a change tracking proxy always also allows to leverage lazy loading is the main reason why the DbContext has this configuration flag:
DbContext.Configuration.LazyLoadingEnabled
This flag is true by default. Setting it to false
disables lazy loading even if proxies are created. This is especially important if you are working with change tracking proxies but don't want to use those proxies for lazy loading as well.
The option ...
DbContext.Configuration.ProxyCreationEnabled
... disables proxy creation completely - for change tracking and lazy loading as well.
Both flags only have a meaning at all if your entity classes meet the requirements for creating either change tracking or lazy loading proxies.
Now, you know the purpose of dynamic lazy loading proxies. So, why should one use dynamic change tracking proxies?
Actually the only reason I am aware of is performance. But this is a very strong reason. Comparing snapshot based change tracking with proxy based change tracking the performance difference is huge - from my measurements a factor of 50 to 100 is realistic (taken from a method which needed around one hour for 10000 entites with snapshot based change tracking and 30 to 60 seconds after making all properties virtual to enable change tracking proxies). This is getting an important factor if you have some application which processes and changes many (say more than 1000) entities. In a web application where you possibly only have Create/Change/Delete operations on single entities in a web request this difference doesn't matter so much.
In almost all situations you can leverage eager or explicite loading to achieve the same goal if you don't want to work with lazy loading proxies. The performance for proxy based lazy loading or non-proxy based explicite loading is the same because basically the same query happens when navigation properties are loaded - in the first case the proxy does the query, in the second case your hand-written code. So, you can live without lazy loading proxies without losing to much.
But if you want reasonable performance to process many, many entities there is no alternative to change tracking proxies - aside from using EntityObject
derived entities in EF 4.0 (not an option in EF 4.1 because it's forbidden when you use DbContext
) or not using Entity Framework at all.
Edit (May 2012)
In the meantime I have learned that there are situations where change tracking proxies are not faster or even worse in performance compared to snapshot based tracking.
Due to these complications when using change tracking proxies, the prefered way is to use snapshot based change tracking by default and use proxies carefully (after doing some tests) only in situations where high performance is required and where they prove to be faster than snapshot based change tracking.