Loading from database without proxy classes?
Asked Answered
C

1

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.

Cutworm answered 13/7, 2011 at 22:37 Comment(2)
I assume that you are using WCF Generated Proxies by adding "Service References" to your project. Is this correct?Duelist
@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 classCutworm
D
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

Dufour answered 13/7, 2011 at 22:51 Comment(5)
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.Cutworm
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!Dufour
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.Cutworm
I see, it is because deferred query execution. You cannot return IQuerybale - you must execute query before you set proxy creation back to true.Dufour
@LadislavMrnka I thought FirstOrDefault() did execute query?Perichondrium

© 2022 - 2024 — McMap. All rights reserved.