-
Notifications
You must be signed in to change notification settings - Fork 0
WhenToTheoriseAndWhenToGet
The functions IQuery.Theorise<T>
and IEntityData.Theorise<T>
are essentially a performance optimisation.
They are designed for use when a developer wishes to express that an entity exists in the data-store but doesn't want to actually retrieve it from the store.
The theorise methods are a performance optimisation, and "premature optimisation is the root of all evil'. If in doubt about whether to use the Theorise
or the Get
methods, choose Get
. Using Get
will result in safer code, which behaves consistently in all scenarios.
The Get
method will go to the data-store in order to retrieve the specified object. In production environments this means a round-trip to the database. If the object does not exist (no row of the specified identity in the corresponding table), then the Get method will return null
.
On the other hand, the Theorise
method does not contact the data-store and in production it does not read the database. Instead it assumes that the specified object exists and returns a stand-in/proxy object which represents the object.
The Theorise method will never return null
.
When the Get
method is used, it retrieves the specified object; its property values/state will be populated using the data-store.
On the other hand, Theorise
does not populate any properties/state of the object except for its identity/primary key value. An ORM backend might provide lazy-loading for this state upon access, but it is not certain to do so.
Theorise should not be used if any state is required from the specified object.
Using Theorise
is appropriate to get a reference to an object which is believed to exist in the data-store. It is useful when all the developer wants/needs is the reference to the object; not any of its state.
Here is an example where we create a query for parcels over 10kg in weight, which are in a specified warehouse.
public IList<Parcel> GetHeavyParcels(long warehouseId)
{
// query is an instance of IQuery
var warehouse = query.Theorise<Warehouse>(warehouseId);
return query.Query<Parcel>()
.Where(x => x.Warehouse == warehouse
&& x.WeightKg > 10)
.ToList();
}
In this example, Theorise was appropriate to get the warehouse
object. This was because the object was only used within a Linq query, and none of its properties/state was used in that query, only its existence.
In this example, we are updating a reference property on one object to point to another. We do not use any state of that newly-referenced object, we only wish to point to it by its identity.
public void TransferEmployee(Employee employee, long officeId)
{
// query is an instance of IQuery
// persister is an instance of IPersister
var office = query.Theorise<Office>(officeId);
employee.Office = office;
persister.Update(employee);
}
As with the previous example, Theorise is appropriate because we do not use any of the state of the office object. All we want to do is to update the employee object to have a different office, identified by its identity/primary key value.
Note that this code is not entirely safe. If the office identified by officeId
does not exist in the data-store then when the model is persisted to the database it could cause an error. In a typical relational database this would be a foreign key constraint violation error. Theorise
is most appropriate when the developer has good reason to believe that the object does indeed exist in the data-store.