How to use Poco Object with Entity Framework and use lazy, eager, and explicit loading
Posted on: 2012-03-15
When using Poco Object you have less stuff automatically done by Entity Framework. This doesn't mean that you have less power of this framework.
You can still use Entity Framework with complex object and this, by using many different loading like lazy loading, eager loading and explicit loading.
Eager Loading with Poco
Eager Loading with Entity Framework and Poco mean that the object will be loaded with 1 query but you need to specify which related object you want to load. This is pretty much the most "performant" way to do it if you know that you will use most of the data object.
var dbContext = new NDbContext("...");
dbContext.Configuration.LazyLoadingEnabled = false;
var XYZs = dbContext.XYZs.Include("MyPropertyThatLinkToAnObjectInsideXYZObject");
foreach (var x in XYZs) {
dbContext.ObjectContext().LoadProperty(x, o => o.XYZInsideObject);
Console.WriteLine("x contain the subobject : " + x.XYZInsideObject.Id);
}
This will produce only one query to the database that will contain a JOIN between the table of XYZ
and XYZInsideObject
.
Explicit loading with Poco
Explicit means that you want to load on demand the information of related object. This mean that you load the information only if desired and you need to specify when to load it explicitly.
var dbContext = new NDbContext("...");
dbContext.Configuration.LazyLoadingEnabled = true;
var XYZs = dbContext.XYZs;
foreach (var x in XYZs) {
dbContext.ObjectContext().LoadProperty(x, o => o.XYZInsideObject);
Console.WriteLine("x contain the subobject : " + x.XYZInsideObject.Id);
}
As you can see, the line 7, it uses ObjectContext()
this method is created by the developer if required when using Poco. This need to be added to your custom DbContext. Normally, this is generated by Entity Framework but since we work with Poco, it's inside the DbContext created manually.
public class NDbContext : DbContext {
public ObjectContext ObjectContext() {
return (this as IObjectContextAdapter).ObjectContext;
}
//...
public DbSet<XYZ> XYZs { get; set; }
//...
}
DbContext hide the complexity of the ObjectContext but to use Explicit, it's require to have access to it.
Lazy loading with Poco object and Entity Framework
POCO entities can have proxy objects that support change tracking or lazy loading (differed loading).
That mean that for using lazy loading you need to activate to true
the property LazyLoadingEnabled
and ProxyCreationEnabled
.
On particularity is that each navigation properties must be declared as public and virtual. This will work for Property to one object or any property that is inherited from ICollection<>
.
var dbContext = new NDbContext("...");
dbContext.Configuration.LazyLoadingEnabled = true;
dbContext.Configuration.ProxyCreationEnabled = true;
/*Default value is true, do not need to set it here*/
var xyzs = dbContext.XYZs;
foreach (var x in XYZs) {
Console.WriteLine("x contain the subobject : " + x.XYZInsideObject.Id);
}
If you try the code above with LazyLoadingEnabled to false, the code will crash with a NullReferenceException to the like 9, where the console try to access the property because it's not loaded.
Entity Framework with Poco
Complex object are well loaded and the way you want with EF. You can lazy load which will create more query to the database as Explicit load or you can Eager load and have less query to the database but more data in the same time. What is great is that you can have all those types of technical stuff under the same project to use the good one for each different task.