In the book "Entity Framework 4 in Action", in section 16.1.3 and again in 16.2.4, it is stated
If you have a proxy instance, remember to disable lazy loading before
serializing, or you’ll end up sending unwanted data to the client.
However, the authors never say how to disable lazy loading. In my own searches, I've heard of ContextOptions.LazyLoadingEnabled. Is that "the way" this is done? Is there more than one way (besides disabling proxy generation)?
I read in one article that the LazyLoadingEnabled flag only pertains to EntityObject entities, not POCO entites:
Turning lazy loading off will now allow your classes to be serialized
properly. Note, this is if you are using the standard Entity
Framework classes. If you are using POCO, you will have to do
something slightly different.
With POCO, the Entity Framework will create proxy classes by default
that allow things like lazy loading to work with POCO. This proxy
basically creates a proxy object that is a full Entity Framework
object that sits between the context and the POCO object. When using
POCO with WCF (or any serialization) just turning off lazy loading
doesn’t cut it. You have to turn off the proxy creation to ensure
that your classes will serialize properly
I suspect the above commentary is simply erroneous.
Yes, ContextOptions.LazyLoadingEnabled is "the way." The serialization issue is related, but different. Proxies have a different runtime type. That can mung serialization. The only relation to lazy loading is that pure (non-proxy) POCOs don't do lazy loading.
Related
So I have code which has created a poco entity (from deserializing JSON). I wish to enable lazy loading for the the entity, so I want Entity Framework to wrap my POCO object and give me an EF proxy that can lazy load navigation properties.
I've seen many answers for questions regarding getting the underlying poco entity from an EF proxy, but not the other way around given. Given a poco entity how do you create an EF proxy wrapping it?
Both...
context.Set<TEntity>().Add(poco);
and...
context.Set<TEntity>().Attach(poco);
...return the poco entity is there a method somewhere that will give me a proxy for the poco?
I'm able to get proxied entities and lazy loading is working fine when I load an entity through...
context.Set<TEntity>().Where(...)
You can't lazy load navigation properties unless you are querying from the context. If you are loading the entity by the deserialization of JSON you need to use explicit loading.
//Example
context.Entry(poco).Reference(x => x.ReferenceProperty).Load();
context.Entry(poco).Collection(x => x.ReferenceCollection).Load();
https://msdn.microsoft.com/en-us/data/jj574232.aspx
I'm using Entity Framework 6 and I have lazy loading enabled:
When I set my entity class Access to 'public, lazy loading works fine:
In the example above, I'm able to navigate from Address to City.
However, if I change the entity class Access to 'internal', then lazy loading stops working and I can no longer navigate from Address to City if I don't eager load City:
Why does lazy loading stop working for internal classes? Is there a way around this?
The entity must be public, it's a requirement for Entity Framework to be able to inherit from it and create a proxy at runtime (that adds all the EF internal stuff in the overridden virtual navigation properties).
See Requirements for Creating POCO Proxies on MSDN.
We are developing a application which should use Entity Framework and its an simple WCf Soap service (not Wcf data service). I am very confused now I have read these following posts but I don't understand where to go This question is almost the same but I have a restriction to use POCOs and try to avoid DTOs. Its not that big service. But the link which I mentioned ,in answer its written that if I try to send POCO classes on wire, there will be problem with serialization.
This post has implemented the solution which related to my problem but he did not mention anything related to serialization problem. He just changed the ProxyCreationEnabled =false which I found in many other articles as well.
But these posts are also little old, so what is the recommendation today. I have to post and get lot of Word/Excel/PDFs/Text files as well, so will it be OK to send POCO classes or it will be problem in serialization.
Thanks!
I definitely do not agree with this answer. The answer mentioned suggests to reinvent the wheel (The answer does not even indicate why not using POCOs).
You can definitely go with POCOs, I see no reason to have serialization issues; but if you have any, you can write DTOs for these specific problematic parts and map them to POCOs in the Business layer.
It is a good practice to use POCOs as the name itself suggests; Plain Old CLR objects. Writing the same classes again instead of generating them will not have any advantage. You can simply test it.
UPDATE:
Lazy Loading: Lazy loading means fetching related objects from database whenever they are accessed. If you have already serialized and deserialized an entity (ex. you have sent the entity to client side over a wire), Lazy Loading will not work, since you will not have a proxy in the client side.
Proxy: Proxy class simply enables to communicate with DB (a very simple definition by the way). It is not possible to use an instance of Proxy in the client side; it does not make sense. Just seperate the Proxy class and POCO entities into two different DLLs and share only the POCO objects with the client. And use the proxy in the service side.
I have an web application that uses NHibernate as ORM. I enable lazy loading for my classes but I want to load some classes without lazy in a special situation.
Now is there any utility or built in class in NHibernate that force a class to load it without lazy in a special situation?
Note: I don't want to remove lazy property in my mapping file, because I use lazy loading in some of time.
Yes. If you are using the ICriteria Api to specify your queries, you can use SetFetchmode to specify eager loading for some of the properties on a per-query basis.
I did a blog post on wrapping the behavior in a query object, it may be useful.
You might try looking at your system in different light.
http://www.infoq.com/presentations/Making-Roles-Explicit-Udi-Dahan
I've started digging into Nhibernate and although there are many things I do like, there is one ting I dislike: the "generate proxy"/lazy load mechanism. The idea that I have to maintain some sort of reference to the ISession and make sure the entities are associated with the session before accessing a property that might trigger lazy-loading is a bit more plumbing in my viewmodels than I appreciate. In the last ORM mapper I used, we had a different approach to lazy loading which enabled used to disregard the session problem entirely at the cost of less POCO entities. I basically want to do the same thing with nhibernate, with some syntax similar to this:
public class Order
{
// this will introduced through the ctor using for ex an interceptor and Castle Windsor
private IOrmService ormService;
List<OrderLine> details = new List<OrderLine>();
public IEnumerable<OrderLine> Details
{
get
{
ormService.LazyLoad(this, o => o.Details);
return this.details;
}
}
}
Where the idea is that the ormService will simply disregard the lazy load request from the entity if the collection has already been loaded (nevermind the state management issue :-)). I looked into the NHibernateUtils-class, which has some Initialized and Initialize-collection methods, but they assume that you are using proxies. Basically, i need a way of telling nhibernate someting like: "hey, populate this property using this session which i'm giving you". The state-management, etc can be handled externally. Is there support for doing this in Nhibernate?
I'm a bit confused with your problem. I feel like following Hibernate best practices should be enough, no need to re-invent what already there. Here are a few comments.
The idea that I have to maintain some
sort of reference to the ISession and
make sure the entities are associated
with the session before accessing a
property that might trigger
lazy-loading is a bit more plumbing in
my viewmodels than I appreciate
If you follow the open session in view pattern, this becomes really easy.
Where the idea is that the ormService
will simply disregard the lazy load
request from the entity if the
collection has already been loaded
That's what the lazy proxy does already.
Basically, i need a way of telling
nhibernate someting like: "hey,
populate this property using this
session which i'm giving you".
That what you do when you detach/attach objects to a session. The lazy items will be loaded according to the session the object is attached to.
The answer is no you cannot have lazy loading without proxies. Either the proxies need to be created by NHibernate or any type of class or pattern you implement will produce the same end result except you'll just have moved around where/how the proxies are generated.
For the lazy loading to work, it inherently needs the ISession otherwise there would be no way for it to connect to the database to retrieve the needed values.
The way NH has implemented its proxies pattern is probably the best you will ever achieve atleast until .NET 4.0 the new dynamic word might shake things up a bit.