7

In Entity Framework 4 Is it possible to choose to load some queries into a POCO without it using proxy classes? (For the purpose of caching that object for future read only use). I am using the Repository - Service pattern.

By this I mean:

var order = _orderService.GetById(1);
// after order is loaded then we can see in the debugger that:
// order.Customer is of type System.Data.Entity.DynamicProxy.Customer_17631AJG_etc

What I want is for the order.Customer to actually use the POCO type MyApp.Models.Entities.Customer instead of a proxy to that type.

EDIT: Based on Ladislav's suggestion to add a "GetUnproxied" method to the Repository, I've made this change:

// this is the current method that must return a DynamicProxy
public IQueryable<T> GetQuery()
{
    return ObjectSet.AsQueryable();
}

// this is the new additional method that must return the plain POCO
public IQueryable<T> GetReadOnly()
{
    ObjectContext.ContextOptions.ProxyCreationEnabled = false;
    var readOnly = ObjectSet.AsQueryable();
    ObjectContext.ContextOptions.ProxyCreationEnabled = true;
    return readOnly;
}

Is this correct?

It does not look thread safe to me. Both methods use the same ObjectContext instance, so it might be possible for ProxyCreationEnabled == false to happen on one thread and then public IQueryable<T> GetQuery() to be called on another thread - which would suddenly mean that the proxy method could return the non proxied object.

John Saunders
  • 160,644
  • 26
  • 247
  • 397
JK.
  • 21,477
  • 35
  • 135
  • 214
  • I assume that you are using WCF Generated Proxies by adding "Service References" to your project. Is this correct? – Yiğit Yener Jul 13 '11 at 22:45
  • @Yigit Ah no I'm using T4 templates to generate my POCO classes. Nothing to do with WCF. What I'm saying is that when I use objectcontext.Get() that it loads the properties of the POCO as proxy classes instead of the actual POCO class – JK. Jul 13 '11 at 22:54

1 Answers1

17

Use this before you query data to turn off proxy creation

context.ContextOptions.ProxyCreationEnabled = false;

I think it can be also turned off globally in EDMX designer.

Update:

This applied to ObjectContext. With DbContext the code is:

context.Configuration.ProxyCreationEnabled = false;

plus I do not see any option in the edmx designer

Gert Arnold
  • 105,341
  • 31
  • 202
  • 291
Ladislav Mrnka
  • 360,892
  • 59
  • 660
  • 670
  • updated question to have two repository methods, one proxied, one without. Can you comment if it is correct, it does not look thread safe to me. – JK. Jul 14 '11 at 22:51
  • 1
    Yes it should work this way. I don't understand your comment about "thread safe". Nothing in EF is thread safe and context should not be shared among threads! – Ladislav Mrnka Jul 14 '11 at 23:29
  • I've just tested it - debugged through line by line, and it calling the GetReadOnly() method, but it still returns a Dynamic Proxy, why would it do that? The code that calls GetReadOnly is: `return _currencyRepository.GetReadOnly().Where(c => c.CurrencyCode == defaultCurrencyCode).FirstOrDefault();`. It did execute the line `ProxyCreationEnabled = false` so I'm not sure why it is still a proxy. – JK. Jul 14 '11 at 23:53
  • I see, it is because deferred query execution. You cannot return `IQuerybale` - you must execute query before you set proxy creation back to true. – Ladislav Mrnka Jul 15 '11 at 06:08
  • @LadislavMrnka I thought `FirstOrDefault()` did execute query? – Alexander Derck Dec 02 '15 at 15:03