views:

175

answers:

3

For example, I have two classes: Foo and Bar. This classes are mapped to some tables.

As for now, I have static methods for each class: Add, Update, Delete, Get.

E.g.: 

public class Foo
{
   private Guid _id;
   private string _someProperty;

   static Foo Get(Guid id);
   static void Add(Foo foo);
   static void Update(Foo foo);
   static void Delete(Foo foo);
}

So, when i need to do smth with my object i say it like so:

Foo foo = Foo.Get(id);

Foo newfoo = new Foo();
Foo.Add(newfoo);

Foo.Update(newfoo);

Foo.Delete(newfoo);

Is it a good approach? If it is not, what approach should i use to access data?

Thanks

+1  A: 

It always depends on the kind of software you are writing.

Personally, I don't like if the entity itself does any data access. The entity is just responsible to manage its fields and properties and should not do more.

In a quite large enterprise software I'm working on we put all the NH access in a separate assembly. HQL and other specific stuff does not belong to the business logic. This makes it also easy to unit test. There is a similar architecture explained on CodeProject, which is worth reading.

I like to have some general methods which allow to insert, delete and update any entity, because it is so easy using NH and you don't have to write the same code over and over again. For instance:

void Store(object entity);
void Delete(object entity);
T Get<T>(object id);
IList<T> GetAll<T>();
void Lock(object entity);

Additional specific methods in specific interfaces, for instance:

IList<Product> GetProductsWithAttribute(string attributeName, string attributeValue);
Stefan Steinegger
+7  A: 

What you are doing is basically an implementation of the Active Record pattern. Many people use it, and it's a perfectly valid approach. If your application is very complex however, or if you have a fetish about separation of concerns, you might find the following helpful:

I recommend a DDD (domain-driven design) approach. DDD uses the so-called repository pattern. DDD segregates your application and its concerns into different layers, "Model/Domain", "Infrastructure" and "Service".

The repository is a pattern that belongs inside the infrastructure layer. Business objects like Customer or Employer (or Monster and Weapon) are inside the model layer and represent the core of your 'domain' (which you try to model), they are also responsible for the business logic. The Service layer can be used to simplify, orchestrate activities that span multiple models.

For each domain model (for instance, your classes Foo and Bar) you have a repository which handles the database access. With this, you have your database calls and your models separated.

public interface IFooRepository
{
     Foo Get(Guid guid);
}

public class FooRepository : IFooRepository
{
     public Foo Get(Guid guid)
     {
         //... DB voodoo magic happening
         return foo;
     }
}

You could also create a generic IRepository<T> if you're sick of writing boiler code for your repositories all the time.

You should also look into dependency injection / inversion of control because this approach works really well with it.

The benefit of this approach is, that you can easily implement new classes that derive from IFooRepository. This allows you to quickly adopt to changes in your database infrastructure. For instance, you could create a FooRepository which reads data from an XML file, or one that reads from a Postgres db with NHibernate.

You can also read this, this and this article about DDD.

kitsune
As a warning tho, ddd can be pretty complex at first, with its terminology of "value objects" and "aggregate roots" etc. Don't despair.
kitsune
This is especially true once you try to model relationships. (For instance, an Employee object has a reference to a Manager.. what happens if you save an Employer, do you have to save its Manager too? Who is responsible for saving it?) The first article of the last paragraph, written by Jimmy Bogard, deals with that.
kitsune
Thanks for your answer. I will try to use a repository pattern just to see is it suitable for me or not. Did you use Active Record pattern? Does Repository pattern make code more cleaner?
Sergey
A: 

If you're writing large applications then what Kitsune says is the best way.

If it's a small set of classes, say less than 5, and not ever going to be a huge enterprise application you could look at this NHibernate query helper (shameless plug) or also the way Codesmith generates its NHibernate classes.

With the first link you simply have your objects holding the data, performing any validation for the business rules: for example having a method called IsValidEmail(). You then use the query manager to perform the Create,Read,Update,Delete tasks, e.g.:

NHibernateManager<User> manager = new NHibernateManager<User>();
User name = manager.ReadFirst();

// All items filtered (using OR)
IList<User> list = manager.OrList("@Name", "12345", "@Name", "54321");

// Paged
list = manager.Page(1,10);

The CodeSmith templates are more advanced than this, but work on a similar principle. They expose you to the NHibernate sessions.

The ActiveRecord pattern you have done is also perfectly fine and will only ever be scorned by domain driven purists. The only issue is the objects such as User, Contact are then responsible for the NHibernate queries and sessions, but conversely the object is nicely self contained.

Which one would you prefer to consume out of 2 (or 3 if you include the Repository pattern) ways of doing it? And ultimately which one is fastest and most appropriate for your project?

Chris S
Well, NHibernateManager you suggested looks very similar to repository pattern. As i have more than 20 entities i think i will try to use the repository pattern(i will create some test project with my entities to see is it better for me or not).
Sergey