-
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, 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 will fully retrieve the specified object and all of 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.
Theorise should not be used if any state is required from the specified object.
Using Theorise
is appropriate when we want a reference to an object which we believe to be in the data-store but all we want is the reference, 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 employee updated, it may cause an error (a foreign key constraint failure in a typical database). Use Theorise
only when your are willing to accept that risk, or have ensured in some other way that the theoretical entity does in fact exist.