What does your data access class look like?
I am using a homemade DataAccess layer and it looks like this:
public class HoneyOpposumDAO : DataAccessObject<lots of generics>
{
public ICollection<HoneyOpposum> Select(Filter filter);
public ICollection<HoneyOpposum> Select();
public HoneyOpposum FindByApplicationId(int id);
internal HoneyOpposum FindByDatabaseId(int id);
void Register(HoneyOpposum o);
void Commit(HoneyOpposum o);
void CancelEdit(HoneyOpposum o);
void Save();
void Save(Filter filter);
void Save(DbTransaction transaction, Filter filter);
void Revert();
void Revert(Filter filter);
void Revert(DbTransaction transaction, Filter filter);
}
Filters
are compound structures for expressing filter expressions in DataSets
.
Basically, this is a 3-tier DataAccess layer:
- Business objects (model)
- DataSets
- Preservation of structure
Business objects must be registered using Register
. Modifications to these objects are confirmed by the model with Commit
and can be undone with CancelEdit
.
Commited business objects can be saved to the underlying save structure (eg SQL Server) using Save
and all changes, since the latter Save
can be reverted using Revert
.
This DataAccess layer provides control over saved and unsaved business objects . It also allows you to create separate databases and application IDs.
Unfortunately the main code is quite complex ... and copyrighted :)
source to share
Call me nuts, but I never use ORM toolkit. The reason is that I'm a control freak and writing all the data manually allows me to always change it to suit my needs, like tweaking lazy loading, etc.
So what happens in DA classes. Basically, DA classes contain functions like
void Save(DomainObject obj)
DomainObject Get(int id)
IEnumerable<DomainObject> Find(SomeQuery)
So what goes in and out of my data access classes are Domain objects. Thus, the DA is responsible for mapping the domain objects to its database representation. In a project I'm currently working on, a client application can pass Lambda expressions as a request. So I can write something like this
IEnumerable<User> users = userDataAccess.Find(usr => usr.FirstName.StartsWith("Pete"));
I will never become static to them. Instead, I'll define the functionality in the interface and let the calling code refer to the interface. This allows me to use inversion of control and dependency injection. Two important concepts for having an application under test.
source to share