Creating Modifying and Deleting Entities
The previous sections show how to query the database using LightSpeed. In many applications you will also want to save changes to the database – adding new entities, modifying or deleting existing ones. As with querying, LightSpeed supports these operations through the unit of work.
How Changes are Saved
LightSpeed saves changes to a unit of work, not an individual entity. When you add, modify or delete an entity, it is not saved immediately. Instead, the unit of work just notes that the entity needs to be saved. When you call IUnitOfWork.SaveChanges(), LightSpeed saves all the entities that need it. This means that you can coordinate the persistence of multiple related changes, and minimises the number of database round-trips.
Adding a New Entity
To add an entity to the unit of work, call IUnitOfWork.Add. The entity itself can be created however you like, typically using the new operator or a factory method.
Creating a new entity and adding it to the unit of work |
Order order = new Order { OrderReference = orderRef }; |
If a new entity is associated with another entity that is already part of a unit of work, it automatically becomes part of the same unit of work. This saves you having to remember to add the entity to the unit of work separately. Any kind of association will trigger this.
Creating a new entity which implicitly becomes part of the unit of work |
Customer customer = unitOfWork.FindById<Customer>(customerId); Order order = new Order { OrderReference = orderRef }; |
Note that because LightSpeed saves units of work, you must add the entity to a unit of work – whether explicitly or implicitly – in order for it to be saved. Just creating the entity is not enough!
As part of adding the entity to a unit of work, LightSpeed assigns an Id to the entity. Before a new entity becomes part of a unit of work, its Id is invalid and should not be used.
Updating an Existing Entity
To update an existing entity, load it into a unit of work and set any required properties to their new values.
Updating an existing entity |
Customer customer = unitOfWork.FindById<Customer>(customerId); customer.Name = "Bob"; |
LightSpeed automatically determines that the entity has changed, and marks it to be saved.
Deleting an Existing Entity
To delete an existing entity, load it into a unit of work and call IUnitOfWork.Remove.
Deleting an existing entity |
Customer customer = unitOfWork.FindById<Customer>(customerId); unitOfWork.Remove(customer); |
If an entity has dependent associations, LightSpeed cascade deletes the dependent entities. This avoids database integrity errors due to foreign key constraints. For example, if every Order is associated with a Customer, and you delete a Customer, then all Orders associated with that Customer are also deleted. However, if the association is not dependent – that is, if your model allows dangling Orders not associated with a Customer – then the Orders are merely detached from the Customer and remain in the database.
You can override the default cascade delete behaviour by setting LightSpeedContext.CascadeDeletes in code or the cascadeDeletes attribute in configuration, or by setting the Cascade Deletes option on an entity (which affects all associations where that entity is the parent), or by setting the Is Dependent option on an individual association.
In all cases, remember that entities are not deleted from the database immediately, but will be deleted when you save the unit of work.
Saving the Unit of Work
When you have made all the changes you need to make, call IUnitOfWork.SaveChanges:
Saving the unit of work |
unitOfWork.SaveChanges(); |
SaveChanges validates all entities that are due to be added or updated, and will not save an invalid entity. (Invalid entities may be deleted.)
By default, the saved entities remain part of the unit of work, in case you want to carry out more changes on them. You can remove them, forcing LightSpeed to reload fresh copies, by calling the SaveChanges(bool reset) overload and passing true. However, it is usually clearer to start a new unit of work for the new batch of activity.
After you have finished with a unit of work, you must call Dispose.
New in LightSpeed 5, Entities now have an Enlisted event which is fired when SaveChanges is enumerating entities for unloading. Also, an OnSaved event has been added to Entity, which is called after SavedChanges() completes Flush(). For more information on these new features, visit the support forums.