Did you know that the default classes generated by the Entity Framework Designer don't have class constructors? And that this is great news?
It means that you can create your own class constructors that will always be used when new entity objects are instantiated. This isn't limited to those times when you explicitly instantiate an object, but also when objects are being materialized from data returned by a query.
This is a great place to infer defaults that cannot be defined in the model itself. A perfect example of this is a default value for an Entity Reference navigation property. Although you can define defaults for an entity's scalar properties in the model, you cannot define defaults for navigation properties.
In my book's sample database, every Customer entity has a CustomerType. CustomerType can be Standard (1), Silver (2) or Gold (3). In the database, the CustomerTypeID foreign key is non-nullable and In the model, this is resolved as a 1:* relationship between CustomerType and Customer - meaning that every Customer must have a related CustomerType.
But the model has no way to define which CustomerType should be used by default.
Although EF will check this constraint when you call SaveChanges, it cannot be otherwise enforced without applying custom business logic.
One place you can insert this logic is in the SavingChanges method, just before the commands are sent to the database. But what if you don't want to wait until that point? More likely, you'll want that default CustomerType to be defined any time a new customer is created in memory.
Enter, the constructor. Because it is not yet defined, you can create a default constructor in the partial class for the entity.
public partial class Customer
{
public Customer()
{
this.CustomerTypeReference.EntityKey =
new EntityKey("EFEntities.CustomerTypes", "TypeID", 1);
}
}Partial Public Class Customer
Public Sub New()
CustomerTypeReference.EntityKey = _
New EntityKey("EFEntities.CustomerTypes", "TypeID", 1)
End Sub
End Class
This constructor will be used for objects coming from the database as well those which you instantiate in code. In the case of the objects materialized from the database, this default will be overwritten by the incoming value, e.g., the actual CustomerType of the Customer coming from the data store. However, in this case, the object's EntityState will remain Unchanged. So you don't have to worry about it screwing up data coming from the database when applying this default.


