You might feel this is homework, for that I am sorry. I have searched but couldn't find a proper answer.
So my question is:
I have several classes and each class has a method to save. So I created a separate class for database handling.
namespace HospitalMgt.Data
{
public static class DBConnection
{
public static string constr = "Data Source=ABD;Initial Catalog=HospitalMgt;User Id=sa;Password=123";
public static SqlConnection con;
// public static SqlCommand com;
public static SqlConnection OpenConnection()
{
con= new SqlConnection(constr);
con.Open();
return con;
}
}
}
However, I don't think it's suitable to implement all the classes with a DBConnection class.
My question :
I found a few articles about DA layers using the Factory method, but according to my knowledge, that pattern does not suit my situation.
Access patterns or query patterns define how the users and the system access the data to satisfy business needs.
A design pattern is an abstraction that does not translate directly into executable code. It is a problem-solving template that can be used as the foundation to design a solution.
A data access layer (DAL) in computer software is a layer of a computer program which provides simplified access to data stored in persistent storage of some kind, such as an entity-relational database. This acronym is prevalently used in Microsoft environments.
Its too old but just came around this question and could not resist to post my thoughts.
I found Repository with UnitOfWork with some descent ORM is good approach. This minimizes most of the issues.
The UoW mentioned in above link can be injected in Repository. That increases the flexibility of usage. Also, all DB Communication code is centralized at one place. The example is not complete but a startup point.
Repository pattern mentioned in above link is actually a generic base class. You can create new class for each of your concrete Repository that derives from it.
Generic repository is considered an anti pattern; there are lot many articles on internet that explains it.
Why generic repository is anti-pattern?
GetById()
, identifier types may be different.I suggest you read these (1, 2, 3, 4, 5) articles explaining why generic repository is an anit-pattern.
Solution:
In any case, do not expose Generic Repository to calling code. Also, do not expose IQueryable
from concrete repositories.
Normally, if I can't use any existing framework, I use both the Repository and Active patterns.
For simplicity, you could use only the Repository pattern. I normally define it like this:
public interface IEntity<T> { }
// Define a generic repository interface
public interface IRepository<TKey, TEntity>
where TEntity : IEntity<TKey>
{
void Add(TEntity entity);
void AddRange(IEnumerable<TEntity> entities);
IEntity<TKey> Get(TKey key);
IEnumerable<TEntity> GetRange(IEnumerable<TKey> keys);
IEnumerable<TEntity> GetAll();
// ..., Update, Delete methods
}
// Create an abstract class that will encapsulate the generic code
public abstract class Repository<TKey, TEntity> : IRepository<TKey, TEntity>
where TEntity : IEntity<TKey>
{
protected Repository(/*parameter you may need to implement the generic methods, like a ConnectionFactory, table name, entity type for casts, etc */) { }
public override void Insert(IEntity<TKey> entity)
{
// do the insert, treat exceptions accordingly and encapsulate them in your own and more concise Exceptions, etc
}
// ...
}
// Create the entities classes, one for each table, that will represent a row of that table
public class Car : IEntity<string> {/* Properties */}
// Create a specific repository for each table
// If the table have a composed key, just create a class representing it
public class CarRepository : Repository<string, Car>
{
public CarRepository() {/* pass the base parameters */}
// offer here your specific operations to this table entity
public IEnumerable<Car> GetByOwner(PersonKey ownerKey)
{
// do stuff
}
}
Obviously, when doing your own implementations, you must take into account thread safety making good using of transactions, specially across diferent entity repositories.
// simple example
ITransaction t = TransactionFactory.GetNewTransaction();
t.begin();
try{
// create person entity
personRepository.Add(person, t);
// create cars assigned to person
carRepository.AddRange(cars, t);
t.commit();
}catch(Exception){
t.rollback();
}
Just be sure that you really want to create your own DAL since it can end beeing extremelly complex, specially trying to develop the most generic solution.
First of all, I would like to recommend you the article Design Patterns for Data Persistence by Jeremy Miller.
There are some data access layer patterns:
I suggest using an ORM, Entity Framework or NHibernate will do nicely. Then you do not have to worry about a db context or create SQL statements.
I suggest you to use a RepositoryBase for all this common operations. If you decide to use an ORM for data access it's good to think in a implementation of repositories based on a Generic Type repository.
Here is a good article about it:
http://lostechies.com/jimmybogard/2009/09/03/ddd-repository-implementation-patterns/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With