Lazy Loading
Lazy Loading is the mechanism used by persistence frameworks
to load demand information. This mechanism
lighter entities, because their associations are loaded only in the
moment that the method that makes the associative data available is
called. So when objects are returned by a query, the
objects are not loaded at the same time, instead they
are loaded automatically when the navigation property is
accessed.
The virtual
f modifier is used by EF to do Lazy Loading , which needs to create proxy instances that will be overridden in these virtual properties.
So you have the impression that this object is always loaded. But in fact he is not. A virtual property is only loaded via lazy loading at the time of the first reference to this property. At this point the EF performs a new query on the database requesting only the data below the object hierarchy of that property.
This can be noticed by debugging your code in Visual Studio, the virtual
property will be loaded the moment you check its value.
Using Lazy Loading can indeed bring performance issues. In your example, if you make a query that returns, say, 100 Pedidos
, without explicitly loading the (eager loading) clients, when referencing any information of Cliente
, for each different client, query in the database. So 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, you can tell that you want EF to Eager Loading from clients using a Include
clause.
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
}
In this way the SQL query will include the clients in the query.
In cases where we do not use the virtual
f modifier, we can only access Cliente
for Eager Loading .
EF uses Lazy Loading by default in properties marked with the virtual
f modifier, otherwise it is turned off and therefore the object reference is null
(except when we use eager loading via Include
).
You can configure EF to not work with Lazy Loading even when we have virtual properties.
public class MeuContexto : DbContext
{
public MeuContexto ()
{
this.Configuration.LazyLoadingEnabled = false;
}
}