Should I enable or disable dynamic proxies with entity framework 4.1 and MVC3?

Entity FrameworkOrmEntity Framework-4.1Ef Code-FirstDynamic Proxy

Entity Framework Problem Overview


Could someone offer up some advice or point out some blogs/articles that could help with making this decision? The proxies seem very foreign to me and I'm hesitant to use them. I like the ability to control Lazy Loading by using virtual properties in my model, but that's pretty much all the benefits that I can see. My application is a simple MVC web application and I don't need to wire up any hooks into the context for when the entities experience a changed state.

Anyway, here's my very limited list of pros and cons right now, let me know if I'm off base with any of this.

Pros

  • On 'Save' or 'Update', I get seamless with 'Apply'Changes'
  • Lazy-Loading configuration is very easy.

Cons

  • Never used proxies before for my entities, this is a change in approach that just seems uncomfortable for myself and fellow team members.
  • Awkward to debug.
  • Requires extra code if I want serialize/de-serialize
  • On 'Save' or 'Update', the proxy must be the same object that was retrieved from the context.

Entity Framework Solutions


Solution 1 - Entity Framework

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.

Solution 2 - Entity Framework

For anyone using Entity Framework 5, be sure to check out the Performance Considerations article. Sections 5 NoTracking Queries and 8 Loading Related Entities offers the info you need to make an informed decision. Cheers.

Solution 3 - Entity Framework

I would suggest NOT using proxies. Dynamic proxy creation breaks or creates complications for components which are dependent on runtime type checking.

Automapper, for instance, will throw a type mismatch / unexpected type error during runtime as your entities will have dynamically generated proxy types during runtime, and not the types you passed in when configuring automapping.

Solution 4 - Entity Framework

Although dynamic proxies have a few nice features, in reality they can create a lot of strange and obscure bugs.

For example a kept a private variable of an entity in one of my classes (it was implementing a batch process) and I was looping through a few millions of records, processing and inserting them in batches, recreating the data context every n-records to clean the memory. Although I NEVER used the private variable, EF was linking it to my new objects (there was a reference through a navigation property) even though I was only setting the reference Id.

This caused all the objects to remain in memory for the entire time the process was running. I had to use AsNoTracking and disable proxies in order for the process to work as expected and memory and performance to return to normal levels. Keep in mind that proxies also reference the context that created them and this can keep in memory huge graphs of entities, it is almost impossible to debug it

So, I believe that you should globally disable the proxies and enable them in small and contained pieces of code. It is very dangerous and impossible to debug such issues expecially when you have large teams coding.

The change tracking is nice, it might justify the usage in some places. The lazy loading can be a huge problem in performance and serialization unless you know what you are doing. I prefer eager or explicit loading at all times.

Solution 5 - Entity Framework

Use Automapper 4.2.1. New version is not having DynamicMap

var parents = parentsRepo.GetAll().ToList();
Mapper.CreateMap<Parent,ParentDto>();
var parentsDto = Mapper.DynamicMap<List<ParentDto>>(parents);

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionmatt_devView Question on Stackoverflow
Solution 1 - Entity FrameworkSlaumaView Answer on Stackoverflow
Solution 2 - Entity FrameworkduoctView Answer on Stackoverflow
Solution 3 - Entity FrameworkCSharkView Answer on Stackoverflow
Solution 4 - Entity FrameworkChrissView Answer on Stackoverflow
Solution 5 - Entity FrameworkMadhusudhana Reddy NadamalaView Answer on Stackoverflow