Dave Donaldson

Critical thinking in software development

Search

Advertisement

Subscribe

Technorati

View blog authority
View blog reactions

My Tweets

Sample Usage of NHibernateRepository

Thursday, November 09 2006

In my last post I went into detail of how and why the NHibernateRepository assembly was created and showed some of its API. I thought it might be nice for developers to also see some examples of how to use it.

One important note: even though the NHibernateRepository assembly makes it dead simple to retrieve and manipulate data using NHibernate, it does expose a public property named Session, which is the underlying NHibernate session. Accessing the Session property allows you to program "directly" against the NHibernate API if you choose to do so.

Retrieving a Single Entity By ID
The following code uses the static Get method from the Repository class to retrieve a Customer entity by its ID.

Customer customer = Repository.Get<Customer>(customerID);

Retrieving a Single Entity By Property
The following code uses the static GetByProperty method from the Repository class to retrieve a Customer entity by its name, where "Name" is a public property defined on the Customer entity and customerName is its value.

Customer customer = Repository.GetByProperty<Customer>("Name", customerName);

Retrieving a Property of an Entity
The following code uses the static GetProperty method from the Repository class to retrieve the value of the name for a given Customer, where "Name" is the property being retrieved, "ID" is the name of the ID property on the Customer entity, and customerID is the actual value of the ID.

string customerName = Repository.GetProperty<Customer, string>("Name", "ID", customerID);

Retrieving a List of Entities with HQL
The following code builds an HQL query and uses one of the overloaded static Find methods from the Repository class to retrieve a list of Order entities that have a total amount greater than or equal to $100.

StringBuilder hql = new StringBuilder();
hql.Append("FROM Order a ");
hql.Append("WHERE a.TotalAmount >= 100.00 ");
hql.Append("ORDER BY a.TotalAmount DESC");

Collection<Order> orders = Repository.Find<Order>(hql.ToString());

Retrieving a List of Entities with HQL that Contains a Single Parameter
The following code builds an HQL query and uses one of the overloaded static Find methods from the Repository class to retrieve a list of Order entities that have a total amount greater than or equal to a specific amount (noted by the question mark in the HQL). The NHibernateUtil.Decimal type is part of the NHibernate assembly.

StringBuilder hql = new StringBuilder();
hql.Append("FROM Order a ");
hql.Append("WHERE a.TotalAmount >= ? ");
hql.Append("ORDER BY a.TotalAmount DESC");

// totalAmount is defined and set elsewhere
Collection<Order> orders = Repository.Find<Order>(hql.ToString(), totalAmount, NHibernateUtil.Decimal);

Retrieving a List of Entities with HQL that Contains Multiple Parameters
The following code builds an HQL query and uses one of the overloaded static Find methods from the Repository class to retrieve a list of Order entities that have a total amount greater than or equal to a specific amount and have an order date specific to a certain date (both parameters are noted by the questions mark in the HQL). IType, NHibernateUtil.Decimal, and NHibernateUtil.Date come from the NHibernate assembly. Note that the array of parameter values and array of parameter types should match up in the appropriate order.

StringBuilder hql = new StringBuilder();
hql.Append("FROM Order a ");
hql.Append("WHERE a.TotalAmount >= ? ");
hql.Append("AND a.OrderDate = ? ");
hql.Append("ORDER BY a.TotalAmount DESC");

// Setup HQL parameter values and types, where totalAmount and orderDate
// have been set elsewhere

object[] paramValues = new object[] { totalAmount, orderDate };
IType[] paramTypes = new IType[] { NHibernateUtil.Decimal, NHibernateUtil.Date };

Collection<Order> orders = Repository.Find<Order>(hql.ToString(), paramValues, paramTypes);


Retrieving a List of All Entities
The following code uses one of the overloaded static FindAll methods from the Repository class to retrieve all Order entities. It simply retrieves all orders from the database and returns them in one big list.

Collection<Order> orders = Repository.FindAll<Order>();

Retrieving a List of All Entities Ordered By a Property
The following code uses one of the overloaded static FindAll methods from the Repository class to retrieve all Order entities and return them in descending order by order date, where "OrderDate" is a property defined on the Order entity.

OrderBy orderBy = new OrderBy("OrderDate", Order.Desc);
Collection<Order> orders = Repository.FindAll<Order>(orderBy);

Retrieving a List of All Entities Ordered By a Property with Max Results
The following code uses one of the overloaded static FindAll methods from the Repository class to retrieve only a certain number of Order entities (in this case 10) and return them in descending order by order date, where "OrderDate" is a property defined on the Order entity. This basically shows how to retrieve the 10 most recent orders.

int maxResults = 10;
OrderBy orderBy = new OrderBy("OrderDate", Order.Desc);
Collection<Order> orders = Repository.FindAll<Order>(orderBy, maxResults);

Retrieving a List of Entities By Property
The following code uses one of the overloaded static FindByProperty methods from the Repository class to retrieve all Order entities with a specific order date, where "OrderDate" is a property defined on the Order entity and date is the actual date value.

// date is defined and set elsewhere
Collection<Order> orders = Repository.FindByProperty<Order>("OrderDate", date);

Retrieving a List of Entities By Property Ordered By a Property
The following code uses one of the overloaded static FindByProperty methods from the Repository class to retrieve all Order entities with a specific order date, but are ordered in descending order by total amount, where "OrderDate" and "TotalAmount" are properties defined on the Order entity.

// date is defined and set elsewhere
OrderBy orderBy = new OrderBy("TotalAmount", Order.Desc);
Collection<Order> orders = Repository.FindByProperty<Order>("OrderDate", date, orderBy);

Retrieving a List of Entities By Property Ordered By a Property with Max Results
The following code uses one of the overloaded static FindByProperty methods from the Repository class to retrieve only a certain number of Order entities with a specific order date, but are ordered in descending order by total amount, where "OrderDate" and "TotalAmount" are properties defined on the Order entity. This basically shows how to retrieve the top 5 most expensive orders for a given date.

// date is defined and set elsewhere
int maxResults = 5;
OrderBy
orderBy = new OrderBy("TotalAmount", Order.Desc);
Collection<Order> orders = Repository.FindByProperty<Order>("OrderDate", date, orderBy, maxResults);

Saving an Entity
The following code uses the Save method from the Repository class to insert an order into the database. Note that you must create a new instance of the Repository class so that you can set the transaction appropriately.

using (Repository rep = new Repository())
{
    try
    {
        rep.BeginTransaction();
        rep.Save(order);
        rep.CommitTransaction();
    }
    catch
    {
        rep.RollbackTransaction();
    }
}

Saving or Updating an Entity
The following code uses the SaveOrUpdate method from the Repository class to insert or update an order in the database (if the order doesn't exist in the database, it will be inserted; otherwise, it will be updated). Note that you must create a new instance of the Repository class so that you can set the transaction appropriately.

using (Repository rep = new Repository())
{
    try
    {
        rep.BeginTransaction();
        rep.SaveOrUpdate(order);
        rep.CommitTransaction();
    }
    catch
    {
        rep.RollbackTransaction();
    }
}

Updating an Entity
The following code uses the Update method from the Repository class to update an order in the database. Note that you must create a new instance of the Repository class so that you can set the transaction appropriately.

using (Repository rep = new Repository())
{
    try
    {
        rep.BeginTransaction();
        rep.Update(order);
        rep.CommitTransaction();
    }
    catch
    {
        rep.RollbackTransaction();
    }
}

Deleting an Entity
The following code uses the Delete method from the Repository class to delete an order from the database. Note that you must create a new instance of the Repository class so that you can set the transaction appropriately.

using (Repository rep = new Repository())
{
    try
    {
        rep.BeginTransaction();
        rep.Delete(order);
        rep.CommitTransaction();
    }
    catch
    {
        rep.RollbackTransaction();
    }
}

Using the Session Property to Run CreateQuery
The following code demonstrates using the Session property from the Repository class to use the NHibernate CreateQuery method to run an HQL query. The HQL query below assumes relationships between an Order, a Customer, an OrderStatus, and a ShippingCarrier entity.

using (Repository rep = new Repository())
{
    StringBuilder hql = new StringBuilder();
    hql.Append("SELECT a.ReferenceNumber, b.Name, c.Status, d.Name ");
    hql.Append("FROM Order a, Customer b, OrderStatus c, ShippingCarrier d ");
    hql.Append("WHERE a.ID = :orderID ");
    hql.Append("AND a.Customer.ID = b.ID ");
    hql.Append("AND a.OrderStatus.ID = c.ID ");
    hql.Append("AND a.ShippingCarrier.ID = d.ID");

    object obj = rep.Session.CreateQuery(hql.ToString())
        .SetParameter("orderID", orderID)
        .UniqueResult();

    if (obj != null)
    {
        object[] temp = obj as object[];
        string referenceNumber = temp[0].ToString();
        string customerName = temp[1].ToString();
        string orderStatus = temp[2].ToString();
        string carrierName = temp[3].ToString();
    }
}

Whew! I think that about does it for now. Hopefully this helps you even more to begin using the NHibernateRepository for your NHibernate needs. And remember that even though the Repository class does most of the work for you when using NHibernate, you can still get to the NHibernate API itself by simply accessing the Session property. Enjoy.

Similar Posts

  1. NHibernateRepository
  2. Generics Rule
  3. ArgumentHelper and Consistent Exception Messages

4 comment(s) so far

Nice and useful! I like the clean use of generics to avoid redundant classes and maintain type-safety.

I've used something similar to this (not as in-depth) for my projects.

Jason Finch wrote on January 23, 2008

Great work!. Now the hard decision is looking at all your good work and the other bits I've seen lately from Billy McCafferty and the Rhino Commons stuff and figuring out an attack vector to it all!

deepak b wrote on January 23, 2008

Greate work done!
I have gone thru the code and I am not able to figure it out "What would be the best approach to use nHibernateRepository in Service Oriented Architecture?

Deepak - NHibernateRepository is best used in your data access layer, well within the service boundaries of a service oriented architecture.

Post your comment

Comment