Lazy Loading
Lazy Loading is the mechanism used by persistence frameworks
to load demand information. This mechanism makes
lighter entities, as their associations are only loaded in the
when the method making the associative data available is
called. So when objects are returned by a query, the
related objects are not loaded at the same time, instead they
are automatically loaded when the navigation property is
accessed.
The modifier virtual
is used by the RU to make the Lazy Loading, that needs to create proxy instances that will be replaced in these virtual properties.
So you have the impression that this object is always loaded. But in fact it is not. A virtual property is only loaded via Lazy loading at the time when there is the first reference to that property. At this time the EF performs a new query in the database requesting only the data below the hierarchy of the object of this property.
This can be noticed by debugging your code in Visual Studio, the property virtual
will be loaded at the exact moment you verify its value.
The use of Lazy Loading may cause performance problems. In your example, if you make a query that returns, say, 100 Pedidos
, without explicitly loading clients (Eager loading), when referencing any information from Cliente
, for each different client, a new query will be made in the database. Therefore in this case you could have 100 new queries to the database.
var pedidos = db.Pedidos.ToList(); // não traz nenhuma informação de cliente
foreach (var pedido in pedidos)
{
var nome = pedido.Cliente.Nome; // aqui é feita a carga por Lazy Loading
}
Eager Loading
To avoid this effect it is possible to inform that you want the EF to do Eager Loading of customers using a clause Include
.
var pedidos = db.Pedidos.Include(m => m.Cliente).ToList(); // inclui cliente na query
foreach (var pedido in pedidos)
{
var nome = pedido.Cliente.Nome; // os dados de cliente já estão carregados
}
This way the SQL query will include clients in the query.
In cases where we do not use the modifier virtual
we will only be able to access the Cliente
for Eager Loading.
The EF uses Lazy Loading by default in properties marked with the modifier virtual
, otherwise it is switched off and so the reference to the object is null
(except when we use Eager loading through Include
).
It is possible to configure the EF so that it does not work with Lazy Loading even when we have virtual properties.
public class MeuContexto : DbContext
{
public MeuContexto ()
{
this.Configuration.LazyLoadingEnabled = false;
}
}
all the answers were great and enlightening, however yours passes an easy explanation and with examples, so the choice of the best, thanks @iuristona
– Rod