Implicit Lazy Loading vs Explicit Lazy Loading - c#

I've been reading Entity Framework and people were crying over why there was not implicit lazy loading or something. Basically I've been searching things about Lazy Loading and now I know what it is : It is a design pattern which allows us to load objects when they are really needed.
But what is the difference between Explicit Lazy Loading and Implicit Lazy Loading.
Thanks in advance...

If you e.g. have an entity "OrderRow" and another entity "Order", there will be a navigational property on the OrderRow that points to the Order it belongs to.
Currently Entity Framework supports only Explicit Lazy Load which means that if you have retreived a number of OrderRows and want to check something on the Order you need to:
// or is an OrderRow
if(!or.Order.IsLoaded)
or.Order.Load()
or.Order.Cancel();
However if you have implicit lazy loading you don't need the IsLoaded check, it will be done automatically, you can do or.Order.Cancel() directly and the Order will be loaded automatically if needed. This is how linq-to-sql works and it saves some typing and some risk for mistakes. On the other hand it makes it less clear exactly when and how database access will be performed. With implicit load it is easy to write inefficient code that makes one DB roundtrip for each line to be fetched from a table.

Explicit means you explicitly wrote your code to lazy load.
Implicit means that the framework (in this case EF) does lazy loading itself, whether you intended to or not.

Related

differences between Eager Loading and Explicit Loading

Eager Loading:
context.Cars.Include(c=>c.Orders)
Explicit Loading:
context.Entry(c).Collection(x => x.Orders).Load();
what's the differences between Eager Loading and Explicit Loading? is it just syntax differences like Eager Loading uses Include while Explicit Loading uses Load?, but isn't that using Include is also an "explicit" way to load navigation properties, so why Eager Loading is not considered the same as Explicit Loading?
Eager loading is the opposite of Lazy loading, but Explicit loading is similar to lazy loading, except that: you explicitly retrieve the related data in code; it doesn't happen automatically when you access a navigation property.
You load related data manually by getting the object state manager entry for an entity and calling the Collection.Load method for collections or the Reference.Load method for properties that hold a single entity.
EntityFramework returns IQueryable objects, which essentially contain the query to the database. But these are not executed until the first time they are enumerated.
Load() executes the query so that its results are stored locally.
Calling Load() is the same as calling ToList() and throwing away that List, without having the overhead of creating the List.
Eager loading loads related entities as part of the query, i.e. the enties are loaded when the query is actually executed. This is the opposite of lazy loading where the related entities are loaded when you access them through a navigation property.
Calling Load() explicitly loads the entities on your request instead of waiting for you to access the navigation properties. It's for example useful when the initial query doesn't return any related entities (because you didn't use eager loading) and you have disabled lazy loading for whatever reason.

Custom Code on Entity Lazy Load

I've written a WPF desktop application, making use of Entity Framework to persist data (code first). I've got lazy loading enabled, which is working great.
For some of my entities, I need to implement some code every time it is instantiated through lazy loading. For example, I save some of my Datatables as lists in the database, and would like to convert these lists back to Datatables whenever the entity is lazy loaded.
I don't want to go through this conversion for the whole project necessarily (as not only can this be somewhat expensive, but for some projects the total objects can exceed available RAM). I also have all the 'custom' code that I'd like to run contained in one method. Lazy loading is therefore perfect, I just need to be able to run some custom code every time an entity is loaded.
So my question: is there any event (or other structure/pattern) that I can utilise or subscribe to so that I can run custom code every time an entity is initialised through lazy loading? I cannot use the parameterless constructor of said entity, as the properties haven't been loaded at that stage.
Thanks to the comments, I've implemented the necessary code in the appropriate get and set accessors. All properties are therefore being 'lazy loaded', which is in line with my requirements. My datatables therefore look as follows:
[NotMapped]
public DataTable MyTable
{
get
{
//Deserialize MyTable from byte[] or string property, obtained from database.
}
set
{
//Serialize MyTable to a byte[] or string property, which is saved to database.
}
}

NHibernate lazy loading but no virtual properties?

I'm experiencing something rather odd. I'm tinkering with NHibernate 3.2 mapping by code and have a very simple object model I'm using just to play.
None of my properties in the entire model are marked as virtual because I dont want lazy loading. I'm mapping by code and in each class mapping I'm setting Lazy(false);
However when it comes to mapping collections, if I try and access a collection after the session has ended I get an error "failed to lazily initialize a collection of role...".
I have to explicitly set collectionMapping.Lazy(CollectionLazy.NoLazy); before it will eager load the collection. It was my understanding that lazy loading was not possible unless your properties in your model were defined at virtuals?
Have I fundamentally missed something?
virtual is needed more than just for lazy loading. NHibernate requires them to be virtual because it creates a run-time proxy of the class and injects behavior.
Virtual properties and methods are only needed for lazy associations (many-to-one or one-to-one) because NHibnerate needs to set a proxy entity on the association property.
Collections (one-to-many and many-to-many) don't need any virtual properties because only the collection is lazy, not the entities in the collection. NHibernate will always use its own collection classes, even if you disable lazy loading.
You still need to use IList<T> instead of List<T>, because NH needs its own collection implementation.
Consider:
You won't get very far in a complex model without lazy loading, except your database fits into RAM or you don't mind to cut you OO model into pieces which destroys both maintainability and performance.
You can have entities without virtual members when you use interfaces to create proxies from. However, you should only use these interfaces to reference to entities, because they could always be proxies.

How to say EF , Don't Load all properties!

There is an Entity with many relationships, when i say to EF load a query on a Entity, it loads all properties(OK) with relationships(i don't want)!
This is a big penalty on performance, because i just need some properties not All relationships.
How to say EF that just load entity's property and Don't load relationships (EntityCollection<TEnitity>) ?
I want load relationships's properties by hand!
Are you sure the navigation properties are being eagerly loaded? They shouldn't be by default. Are you using POCO or Code First? If you are, then you need to make sure your navigation properties are marked "virtual". Virtual properties will be lazy loaded.
To check whether navigation properties are lazy loading or eager loading, you'll want to use a tool like SQL Profiler.
JohnnyO is correct; The default value for ObjectContextOptions.LazyLoadingEnabled is false. However, when I create a model from the database, the default value for the model is true. If you are using the generated EF classes, try setting this to false.

LINQ to SQL: On load processing of lazy loaded associations

If I have an object that lazy loads an association with very large objects, is there a way I can do processing at the time the lazy load occurs? I thought I could use AssociateWith or LoadWith from DataLoadOptions, but there are very, very specific restrictions on what you can do in those. Basically I need to be notified when an EntitySet<> decides it's time to load the associated object, so I can catch that event and do some processing on the loaded object. I don't want to simply walk through the EntitySet when I load the parent object, because that will force all the lazy loaded items to load (defeating the purpose of lazy loading entirely).
Subscribe to the ListChanged Event
EntitySet<T> exposes an event called ListChanged which you can use to detect if an item is being added. Evaluate the ListChangedType property of the ListChangedEventArgs. Here's a link to the values available in the ListChangedType enum.
There is no danger of forcing the load to execute as long as you avoid requesting the enumerator.
http://msdn.microsoft.com/en-us/library/system.componentmodel.listchangedtype.aspx
I don't see any extensibility points for this available; the only thing I can see is in the FK entity there is a Created method on each individual object that gets fired from the constructor...
So the constructor calls created, and personally, I'm not 100% sure that the entity set loading creates each individual object at that time, and fires the event...
HTH.
There are a bunch of built in extensibility methods to the datacontext and data classes generated by Linq2SQL.
http://msdn.microsoft.com/en-us/library/bb882671.aspx
http://csainty.blogspot.com/2008/01/linq-to-sql-extending-data-classes.html
Either of these may be able to serve the purpose you need.
You are definitely not bound to use the default EntitySet<> but can use any IList<> collection instead. I did a little reflection on EntitySet<> but have found no hook into the Load() method, which implements enumerating the lazy source of the entity set (it's where the EntitySet actually gets queried and materialized).
Linq To SQL will use the Assign() method to assign an IEnumerable source (which is lazy by default) to your collection. Starting from there, you can implement your own lazy loading EntitySet with a custom hook at the point you first enumerate the source collection (execute the query).

Categories