Using Entity Framework 6.0, I am attempting to implement table splitting to improve query performance on tables with columns that contain BLOB data. I have followed the recommendations in this tutorial and it does indeed work as described.
Here's a very simplified example of the entity classes that map to one of my split tables ...
public class MyEntity
{
public string Id { get; set; }
public virtual MyEntityContent Content { get; set; }
public string Name { get; set; }
}
public class MyEntityContent
{
public string Id { get; set; }
public virtual MyEntity Entity { get; set; }
public byte[] Blob { get; set; }
}
... and the corresponding configuration code in the associated DbContext
implementation ...
modelBuilder.Entity<MyEntity>().HasKey(e => e.Id).ToTable("MyEntities");
modelBuilder.Entity<MyEntityContent>().HasKey(c => c.Id).ToTable("MyEntities");
modelBuilder.Entity<MyEntity>().HasRequired(e => e.Content).WithRequiredPrincipal(d => d.Entity);
Given that the lazy-loaded Content
property is Required
by Entity Framework, it seems sensible to initialize it to a default value in the constructor of the containing MyEntity
class ...
public MyEntity()
{
Content = new MyEntityContent();
}
... which enables a new instance of the class to be created and partially populated, without the risk of an exception being thrown by forgetting to initialize the required property value:
var entity = new MyEntity {Id = "XXX", Name = "something"};
I typically use a similar technique to initialize collection properties on EF entities and it works fine. However, in the above scenario, this initialization in the constructor has an unexpected effect: when retrieving existing entity instances from the database, the database value in the lazy-loaded property is ignored in favor of the empty default value.
This seems illogical to me. Doesn't Entity Framework create an entity object by first calling its default constructor and then applying its own property values to the created instance? If so, this should overwrite my default Content
property value with a new instance of MyEntityContent
, based on database data. This is how it seems to work with lazy-loaded collection properties.
If it's not possible to do this in the way I am expecting, is there an alternative technique for initializing lazy-loaded properties?