The difference between the Repository pattern and the legacy Data Access class (DAL class) pattern A typical DAL object directly performs data access and persistence operations against storage, often
at the level of a single table and row. Simple CRUD operations implemented with a set of DAL classes
frequently do not support transactions (though this is not always the case). Most DAL class
approaches make minimal use of abstractions, resulting in tight coupling between application or
Business Logic Layer (BLL) classes that call the DAL objects.
When using repository, the implementation details of persistence are encapsulated away from the
domain model. The use of an abstraction provides ease of extending behavior through patterns like
Decorators or Proxies. For instance, cross-cutting concerns like
caching
, logging, and error handling
can all be applied using these patterns rather than hard-coded in the data access
code itself. It’s also
trivial to support multiple repository adapters which may be used in different environments, from
local development to shared staging environments to production.
Implementing Unit of Work A
unit of work
refers to a single transaction that involves multiple insert, update, or delete operations.
In simple terms, it means that for a specific user action, such as a registration on a website, all the
insert, update, and delete operations are handled in a single transaction. This is more efficient than
handling multiple database operations in a chattier way.
These multiple persistence operations are performed later in a single action when your code from the
application layer commands it. The decision about applying the in-memory changes to the actual
database storage is typically based on the Unit of Work pattern. In EF, the Unit of Work pattern is
implemented by a
DbContext
and is executed when a call is made to
SaveChanges
.
In many cases, this pattern or way of applying operations against the storage can increase application
performance and reduce the possibility of inconsistencies. It also reduces transaction blocking in the
database tables, because all the intended operations are committed as part of one transaction. This is
more efficient in comparison to executing many isolated operations against the database. Therefore,
the selected ORM can optimize the execution against the database by grouping several update
actions within the same transaction, as opposed to many small and separate transaction executions.
The Unit of Work pattern can be implemented with or without using the Repository pattern.