maandag 30 april 2007

NHibernate Session Management in Domain Driven App's

As I've posted earlier, Billy McCafferty has written an excellent article on using NHibernate within ASP.NET applications.
In this article, he describes how to use the 'Open Session in View' pattern. This is perfectly useable and a very clean way of working with NHibernate in a DDD ASP.NET application, unfortunately, it is -imho- less (or not) useable in a WinForms application.
The 'Open Session in View' pattern implies that a new NHibernate ISession object is created at each request, and closed at the end of each request. (Changes are committed as well).

It is very important that the Repositories keep their hands off of Transaction Management. In other words: a repository should not start, commit or rollback a transaction. This is natural, since the repository doesn't know anything of the 'context' of the Unit of Work. Therefore, transaction managment should be a responsability of the client (the UI, the Service layer, whatever).
To achieve this, Billy stores the current ISession in the CallContext or HttpContext (he has made abstraction of which implementation is used offcourse. CallContext is used in the case of a WinForms app or a Unit-Test project, HttpContext is used in case of an ASP.NET app; see the source-code that accompagnies the article for more details).
In this way, the repositories can easily access the current ISession when they need it by just getting it out of the CallContext or HttpContext, and the ASP.NET application (the ASP.NET webpages) have access to the ISession as well, so they can start, commit and rollback the unit-of-work.
This is the ideal solution in ASP.NET, since you only need one 'ISession' on each request. At the end of the request, the Session can be closed (committed / rollbacked), so they're short-lived, and this is perfect.

However, in a WinForms application, you'll probably want more then one 'Unit of Work' at the same time, and therefore, have more then one open ISession at the same time.
An example will clarify this a bit more:

Suppose you've a WinForms application which consists of a form which lists all Customers. You can edit a customer by double-clicking it; a 'Customer-Detail' form will open up, where you can make changes to the Customer.

Now, what happens if you edit a Customer ? You'll retrieve the ISession from the CallContext, load the Customer from the DB, make some changes and confirm the changes; closing the form will close the ISession.
So far, no problem. However, what happens if you open another Customer-Detail form before you've committed the changes to the first Customer ?
What if you have 2 Customer Detail Forms open, make changes to Customer 1, save the changes and close the form. Afterwards, you want to save the changes to Customer 1... The problem now is that you've closed the ISession when you've closed the first Customer-Detail form. Customer 2 was attached to the same session which is now closed. If you want to save the changes to customer 2, you'll need an ISession, so you'll require a new ISEssion in this case. Then, NHibernate will think that Customer 2 is a new Customer, and will try to insert a new record to the DB where in fact, the existing Customer needs to be updated.

In my opinion, it is better to have a seperate Unit Of Work (ISession) for each instance of the CustomerDetail form in this case.
This implies that you should create a new ISession for each instance of the CustomerDetail form: this means that the ISession cannot be kept in the CallContext since otherwise, each form would share the same ISession.
Then... how should this be solved ? In my humble opinion, the best way to solve this is to create an ISession when an instance of a form is created, pass it to the repositories, and use it to handle the transaction(s) in the form:

public class CustomerDetailForm : Form
{
private ISession _unitOfWork;

private CustomerRepository _custRep;

private Customer _customer;

public void ShowCustomer( int customerId )
{
_unitOfWork = AppSettings.Instance.SessionFactoryObj.OpenSession();

_custRep = new CustomerRepository(_unitOfWork);

_customer = _custRep.GetCustomer(customerId);

// Disconnect from the DB, since we do not need DB action at this time
// anymore.
_unitOfWork.Disconnect();

}

public void OKButton_Click(object sender, EventArgs e )
{
// Reconnect to the DB
_unitOfWork.Reconnect();

ITransaction tx = _unitOfWork.BeginTransaction();
_custRep.Save (_customer);
tx.Commit();
}
}

I don't know if there's any better / cleaner way of doing this... If you know one, please let me know. :) It is offcourse cleaner if you could abstract the use of NHibernate's ISession by creating a class which encapsulates the ISession, but I wanted to keep things a bit sparse. :)

vrijdag 27 april 2007

Article: NHibernate best practices with ASP.NET

Billy McCafferty has written an excellent article on NHibernate and Domain Driven Design. It can be found here on the CodeProject.
Although it is focused on using NHibernate in ASP.NET, it is still very interesting even if you do not develop in ASP.NET. He talks about a few key concepts in DDD, and the example code is also very interesting.
There's one little drawback however in his example code: although he mentions that the way of working he demonstrates should work for Winforms development as well, I do not completely agree on that. However, I've to investigate it a bit more, which I'll do as soon as I find some time. Once done, I'll post my findings offcourse.

zondag 22 april 2007

Split

When I started this weblog in december 2005, I decided to blog about software development and about photography.

Now, 1 and a half year later, it seems to me that this was not such a good idea; I feel that software engineering and photography do not share the same audience.
Now, you probably think, did it really take you that long to acknowledge this fact ? Well, not really: during the first few months of blogging, the number of photography posts here was pretty low. At this time, I've noticed that 3 out of the 5 last posts were tagged with 'photography', so that's why I've finally decided to split things up.

This will remain my weblog that is focussed on programming (notice that I've changed the name from 'weblog' to 'devlog' as well :) ). Things that are focused on photography will appear on my photolog, so if you're interested, you can have a look there :).

I've choosen Wordpress to host my photo-blog, since Wordpress allows me to import posts from blogger, and that's what I've done: I've imported all the 'photography-tagged' posts from this weblog in my wordpress photo-blog, and translated them to dutch.

vrijdag 13 april 2007

.NET 1.1: Problems when selecting rows from a DataTable using an aggregate filter

I came accross a rather weird error today when I was working in C# 1.1. I was trying to select the records that exist in a DataTable that had more then one child in a related datatable.


To make things a little bit more clear, I've reproduced this by creating a Typed Dataset which contains 2 tables from the Northwind database:



What I want to do, is to select the Categories for which there are multiple products classified into.
So, this is what I've done; I created an instance of this dataset, and populated it with some data:

NorthwindDS ds = new NorthwindDS();
NorthwindDS.CategoriesRow c1 = ds.Categories.NewCategoriesRow();
c1.CategoryID = 1;
c1.CategoryName = "Category 1";
ds.Categories.AddCategoriesRow (c1);

NorthwindDS.CategoriesRow c2 = ds.Categories.NewCategoriesRow();
c2.CategoryID = 2;
c2.CategoryName = "Category 2";
ds.Categories.AddCategoriesRow (c2);

NorthwindDS.ProductsRow p1 = ds.Products.NewProductsRow();
p1.ProductID = 1;
p1.CategoryID = 1;
p1.ProductName = "Product 1";
ds.Products.AddProductsRow (p1);

NorthwindDS.ProductsRow p2 = ds.Products.NewProductsRow();
p2.ProductID = 2;
p2.CategoryID = 1;
p2.ProductName = "Product 2";
ds.Products.AddProductsRow (p2);

// The following line is important to illustrate the problem :)
ds.AcceptChanges();

This is pretty simple, I've just populated the Dataset with 2 categories and 2 products, and the 2 products are both linked to Category 1.
Now, the Query I've talked about earlier should thus return 1 Category, specifically, Category 1, since there's more then one product related to this category.
I do this using the following code:

string filterExpression = "COUNT (Child.CategoryID) > 1";
DataRow[] dr = ds.Categories.Select (filterExpression);

foreach( NorthwindDS.Category cat in dr )
{
Console.WriteLine (cat.CategoryName);
}

This gives me the expected result, it writes 'Category 1' to the output-window.
However, suppose that I've populated this Dataset with data coming from the Database, and that I add a product - record to this Dataset after the Dataset has been populated...
I can simulate this by adding a ProductRow to the DataSet after the 'AcceptChanges()' call:


// previous lines which create the dataset, and add the categories
// and the first 2 products are left out for brevity
ds.AcceptChanges();

NorthwindDS.ProductsRow p3 = ds.Products.NewProductsRow();
p2.ProductID = 3;
p2.CategoryID = 1;
p2.ProductName = "Product 3";
ds.Products.AddProductsRow (p3);

filterExpression = "COUNT (Child.CategoryID) > 1";
DataRow[] dr = ds.Categories.Select (filterExpression);

foreach( NorthwindDS.Category cat in dr )
{
Console.WriteLine (cat.CategoryName);
}

Now, I would expect that this gives me the exact same result as before, however, I get an exception:

An unhandled exception of type 'System.Data.VersionNotFoundException' occurred in system.data.dll

Addition information: There is no original data to access.

Probably, .NET wants to access the original contents of my new ProductRow, but since it is a new one, it has no Original DataViewRowState ...
I've tried to work around this by specifying that the CurrentRows should be used:

ds.Categories.Select (filterExpression, 
string.Empty,
DataViewRowState.CurrentRows);

But, to no avail. (Which didn't surprise me, because this line just says: return the Current DataViewRowState of the Categories and the problem seems to occur when the Product datarows are accessed).

So, this seems to be a bug in the .NET 1.1 (I've tried this in .NET 2.0 as well, and there, it works like a charm).

So, is there anybody who knows how to solve or work around this issue ?

zondag 1 april 2007

Tagliatelle - scampi

Tagliatelle - Scampi

vrijdag 9 maart 2007

Oudenaarde by Night

Yesterday evening, I've been walking around in Oudenaarde - the city were I'll be living in in the near future -, and I've taken these photographs.

oudenaarde stadhuis

oudenaarde walburga carillon

zondag 25 februari 2007

DDD: implementing persistence using NHibernate

Introduction

At last, I've found some time to sit down and begin writing what should be the last part of this 'Domain Driven Design Quickstart' series of articles. In this final article, I will implement the persistence of the domain model that I’ve created in the previous parts of this series. (part I, part II and part III).

To implement the persistence functionality of the domain model, I will use an O/R mapper. I’ve opted to use NHibernate as O/R mapper for this project.
I will not make an in-depth coverage of NHibernate in this article, since this is a bit beyond the scope of this article. Besides, there are various excellent resources on (N)Hibernate available. The book Hibernate in Action, for instance, is an excellent resource to learn about (N)Hibernate, and it offers also some more insights in the O/R principle.


The Database Schema

To get the information in a database, we need a database first (clever :) ). So, I’ve created this ERD:



I’m not going to elaborate on this database-schema since I presume that you have enough knowledge of databases / database-modelling, etc… So lets hop to the next phase.

NHibernate configuration

NHibernate is an O/R mapper which lets you persist your data to a number of supported databases. To be able to use it however, it needs to be setup properly; in .NET this can be easily done in the configuration file of your project.
For this project, I’ll create a WinForms application, and I’ll make some changes to the app.config file to configure NHibernate. This is done like this:


<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="nhibernate"
type="System.Configuration.NameValueSectionHandler,
System, Version=1.0.5000.0,Culture=neutral,
PublicKeyToken=b77a5c561934e089"/>
</configSections>
<nhibernate>
<add key="hibernate.connection.provider"
value="NHibernate.Connection.DriverConnectionProvider"/>
<add key="hibernate.dialect"
value="NHibernate.Dialect.MsSql2000Dialect"/>
<add key="hibernate.connection.connection_string"
value="Data Source=localhost;
Initial Catalog=SomeShop;
Integrated Security=SSPI"/>
</nhibernate>
</configuration>

As you can see, I need to define the nhibernate configuration section first. Once this is done, I specify to which type of database NHibernate will have to talk to (SQL Server 2000), and I also specify the connection string that must be used.

If you use Microsoft Visual Studio.NET 2005, you might come across some unwanted error/information messages concerning the nhibernate config section. I’ve written another post about this problem, and how to solve it a while ago. You can read it here.

Now we’ve configured our project to use NHibernate, but we also need to tell NHibernate how our classes should be mapped to our database-schema. This can be done by creating NHibernate mapping files which describe how a class should be represented in the database. Those mapping files are nothing more then XML files. As I’ve said earlier, this is not an NHibernate tutorial, but merely an article on how NHibernate can be incorporated in a Domain Driven Design project. Therefore, I will not post all the mapping files here or explain them in detail. I will post 2 mapping files here however, and explain them a bit.

NHibernate mapping files

For each class in my domain model, I create an NHibernate mapping file in my Visual Studio.NET project which contains my business classes.
In this specific case, I have a Class Library project which contains the ‘Customer’, ‘Order’, ‘OrderLine’, etc… business classes, so it is in this class library that I also create the NHibernate mapping files.

The mapping file for the Order class, for instance, looks like this:

<xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class name="SomeShopDomain.Order, SomeShopDomain"
table="[Order]" lazy="false">
<id name="Id" column="OrderId" type="Int32"
unsaved-value="-1"
access="field.camelcase-underscore">
<generator class="identity" />
</id>
<property name="OrderDate" column="OrderDate"
access="field.camelcase-underscore" />
<property name="Status" column="OrderStatus"
access="field.camelcase-underscore" />
<property name="Discount" column="Discount"
access="field.camelcase-underscore" />

<many-to-one name="OwningCustomer" column="CustomerId"
class="SomeShopDomain.Customer, SomeShopDomain"
not-null="true"
access="field.camelcase-underscore"
/>

<bag name="OrderLines" cascade="save-update"
inverse="true"
access="field.camelcase-underscore">
<key column="OrderId" />
<one-to-many class="SomeShopDomain.OrderLine, SomeShopDomain"/>
</bag>

</class>
</hibernate-mapping>

This is not the most simple mapping-file in the project, since the Order class contains a collection of OrderLines, so this relationship is reflected in the mapping file.

But, it is maybe better if I just explain the complete mapping file a bit .

As you can see at the beginning of the file, this file describes how the Order class should be mapped to the Order table in the database.
The 'id' element tells NHibernate that the Id property of the class should be used to identify each Order. This element also defines that the Id property of the class maps to the OrderId column in the Order table. The data-type is also defined in there, and it is stated that instances of the Order class that have a value of -1 for the Id property, are New/transcient (unsaved).
Now, NHibernate will use the Id property of the Order class to get or set the value of the Id.
This however, has some disadvantages in my opinion: what if you have some specific logic in the setter-part of the property, some validation-logic for instance ? When NHibernate loads an object out of the database, should this logic be executed ? In my humble opinion not. When an object is loaded from a persistent state, the values of the object must be set, without performing any extra logic.
Another problem pops up when the property is read-only. In this case, Id is an 'identification', and the programmer that uses the Order class, shouldn't be able to change this property. Therefore, this property has only a getter in the Order class, and no setter. NHibernate will have a problem with that: it will throw an exception saying that it cannot set the value of the Id property since it has no setter.
That's why I use the access attribute. With this attribute, I tell NHibernate that it should use the field instead of the property, and that it can find this field by taking the property-name that I've defined in the mapping file, prefix it with an underscore, and make the first character lowercase.
So, in this case, instead of setting the Id property, NHibernate will look for a field in the Order class which is called _id and give this field the value of the OrderId column. By using the field instead of the property, I'm always sure that no extra logic will be executed, and I do not have to bother with getter-only properties.
You can read more about this here and here Particulary in the comments of these articles.
The following three properties are quite straightforward. These elements just say to which column each property maps, and I've also defined that NHibernate should use the field instead of the property to get / set these properties.

The next two elements are bit more interesting though.
The many-to-one element defines how the relationship between Order and Customer must be saved. As you might remember, the Order class holds a reference to the Customer to which the order belongs. To be able to populate the OwningCustomer property which contains this reference, and to be able to save the link with the Customer when the Order is saved, the many-to-one element is used. A Customer can have many Orders, and an Order always belongs to one Customer. The many-to-one element just says that the OwningCustomer property maps to the CustomerId column in the Order table, and that the OwningCustomer is of the type SomeShopDomain.Customer. By defining this type, NHibernate knows that it should look for a mapping file which should be called SomeShopDomain.Customer.hbm.xml in where the mapping of the Customer type is defined.
Mapping files should be named after the class for which they contain the mapping, and should have the extension hbm.xml. Next to that, you also have to specify 'embedded resource' as build action for the mapping files.
The <bag> element defines that the Order contains a collection of OrderLines, and that these objects must be of type SomeShopDomain.OrderLine. NHibernate will use the mapping-file of the OrderLine class to determine in which table those OrderLines must be saved.
The <key> element states that the Id of the current Order must be saved in the OrderId column of the table where the OrderLines will be saved.


This concludes the quick tour of the NHibernate mapping file. For more information about the possible elements, I'll refer to the Hibernate in Action book, or to the Hibernate documentation.

The mapping file of the OrderLine class, looks like this:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class name="BlogShopDomain.OrderLine, BlogShopDomain"
table="OrderLine" lazy="false">
<id name="Id" type="Int32"
column="OrderLineId"
unsaved-value="-1"
access="field.camelcase-underscore">
<generator class="identity" />
</id>
<property name="ArticleName" column="ArticleName"
access="field.camelcase-underscore" />
<property name="ArticlePrice" column="ArticlePrice"
access="field.camelcase-underscore" />
<property name="ArticleId" column="ArticleId"
access="field.camelcase-underscore" />
<property name="NumberOfItems" column="NumberOfItems"
access="field.camelcase-underscore" />

<many-to-one name="OwningOrder" column="OrderId"
class="BlogShopDomain.Order, BlogShopDomain"
access="field.camelcase-underscore"
not-null="true" />

</class>
</hibernate-mapping>
I'm not going to elaborate on this file, so lets get to the next part. :)

Integrating NHibernate in the project

At this point, I've done some necessary configurations, but some coding needs to be done as well.
NHibernate uses the concept of Sessions as an 'interface' between your objects and the database. A session can be considered as a unit of work. This is a bit a simplistic definition, but you can find a better one in the Hibernate documentation or in Hibernate in Action.
To be able to create Sessions, you'll need a SessionFactory. Unlike Hibernate Sessions, a SessionFactory is an expensive object to instantiate, so it's best practice to create this object only once.
Therefore, I like to create a Singleton class which holds amongst some other stuff, the NHibernate ISessionFactory:

public class ApplicationSettings
{
private static ApplicationSettings _instance;

private ApplicationSettings() {}

// The only access point to the ApplicationSettings instance.
public static ApplicationSettings Instance
{
get
{
if( _instance == null )
{
_instance = new ApplicationSettings();
}
return _instance;
}
}

private ISessionFactory _sessionFactory = null;

public ISessionFactory SessionFactoryObj
{
if( _sessionFactory == null )
{
Configuration cfg = new Configuration();
cfg.AddAssembly (typeof(SomeShopDomain.Customer).Assembly);
_sessionFactory = cfg.BuildSessionFactory();
}
return _sessionFactory;
}

}

This structure guarantees that I'll have only one ISessionFactory in my project, and that this SessionFactory is created only once.
The code to create the ISessionFactory is quite simple; first of all a Configuration object is instantiated, and the assembly which contains the business classes is added to the Configuration. As you can see, I use reflection to find that assembly, since I don't want to be bothered with assembly-names and locations. After that, the BuildSessionFactory method is called which creates the ISessionFactory.
This ApplicationSettings class is not part of my class library which contains the domain, but belongs to the project that contains my client application (in this case, a WinForms application). More on that later.
At this time, we can create ISessions.

ISession s = ApplicationSettings.Instance.
SessionFactoryObj.OpenSession();

Creating Repositories for our Domain classes

In Domain Driven Design, getting objects from a persistence store, and getting objects into a persistence store, is being abstracted by the use of repositories.
As you might have seen in the previous articles of this serie, I've already created 'dummy' repositories for the unit-tests.
Now, it is time to implement the 'real' repositories, which will actually do the work of loading / storing objects to our database.
In the 2nd part of this serie, I've already mentionned the existence of the DomainSettings class and the RepositoryFactory interface.
At that point, I've only implemented the 'mock-repositories', but now, I want to implement repositories which use NHibernate to do some real work. This means that I'll have to create an NHibernateRepositoryFactory class. I choose to put this class, along with the NHibernate-repositories in the same project / assembly where my business classes reside.
The NHibernateRepositoryFactory class must implement the IRepositoryFactory interface, which looks like this:

public interface IRepositoryFactory
{
ICustomerRepository CreateCustomerRepository();
IOrderRespository CreateOrderRepository();
...
}

There's one caveat here however... When using databases you'll be faced with 'Transactions'. A repository should not be the initiator nor the 'committer' of a transaction.
Why? The repository has no knowledge of the 'context' of the situation. The repository does not know when it should initiate and commit or rollback a unit-of-work.
As I've told earlier in this article, the NHibernate Session object is the NHibernate object which 'controls' a unit-of-work. Therefore, I'd like to extent the IRepositoryFactory interface with methods which allow me to create a specific repository with an object which is responsible for transaction-handling injected into it:

public interface IRepositoryFactory
{
ICustomerRepository CreateCustomerRepository();
IOrderRespository CreateOrderRepository();
...

ICustomerRepository CreateCustomerRepository( object transHandler );
IOrderRepository CreateOrderRepository( object transHandler );
}
This allows me to create repositories which can take part in a specific transaction/unit-of-work, and it also allows me to create repositories without having to take care about transactions. (This is also necessary; as you can see in the code in the Customer class in part 2 of this serie. There I need to retrieve a value, which is given to me by a repository. In this case, I do not really need a transaction context).

I've chosen to define the transHandler in my CreateXXX methods in the IRepositoryFactory as an object, since I do not want to couple the IRepositoryFactory interface with NHibernate.

At this time, I can already start writing an implementation of a NHibernateRepositoryFactory:

public class NHibernateRepositoryFactory :
IRepositoryFactory
{
public IOrderRepository CreateOrderRepository()
{
ISession s = DomainSettings.Instance.SessionFactoryObj.OpenSession();
return new NHibernateOrderRepository(s);
}

public IOrderRepository CreateOrderRepository( object transHandler )
{
// convert the transHandler to an NHibernat ISession object.
ISession s = transHandler as ISession;

if( s == null )
{
throw new ArgumentException ("object of type NHibernate.ISession expected.",
"transHandler");
}

return new NHibernateOrderRepository (s);
}
}
The NHibernateOrderRepository can look like this:
public class NHibernateOrderRepository :
IOrderRepository
{
private ISession _context;

public NHibernateOrderRepository( ISession s )
{
_context = s;
}

public Order GetOrder( int id )
{
return _context.Get (typeof(Order), id) as Order;
}

public decimal GetOrderTotalForCustomerSinceDate( Customer c, DateTime date )
{
string hql = "select sum (ol.NumberOfItems * ol.ArticlePrice) " +
"from Order o, " +
"OrderLine ol, Customer c " +
"where ol.OwningOrder = o and o.OwningCustomer = c " +
" and c.Id = :custId and o.OrderDate >= :orderDate";

IQuery q = _context.CreateQuery (hql);
q.SetInt32 ("custId", c.Id);
q.SetDateTime ("orderDate", date);

object o = q.UniqueResult ();

if( o == null || o == DBNull.Value )
{
return 0;
}
else
{
return Convert.ToDecimal (o);
}
}
}
I will not elaborate here on the HQL and the specific ISession methods which I've used in the code above, since this would be truly outside the scope of this article. For more information, I'd refer -again- to the Hibernate documentation or the Hibernate in Action book.
I do like to mention though that the bug which I've mentionned here is fixed in NHibernate 1.2.0 CR1. :)


As I'm typing this, I now also see that it would be better to let the repositories implement the IDisposable interface. In the Dispose method. In the Dispose method of the NHibernateRepositories, I can then check if my _context is still open, and close it if it is.
Then, I should also change the code in the Status property of the Customer class, so that it looks like this:

public CustomerStatus Status
{
get
{
CustomerStatus result = CustomerStatus.Normal;

using( IOrderRepository or =
DomainSettings.Instance.
RepositoryFactoryObj.
CreateOrderRepository () )
{
decimal orderTotal = or.GetOrderTotalForCustomerSinceDate(this,
DateTime.Now.AddMonths (-3));

if( orderTotal > DomainSettings.GoldAmountTreshold )
{
result = CustomerStatus.Gold;
}

}
...
return result;
}
If I don't do this, the ISession which is used by the OrderRepository would be kept open.


Using NHibernate in the client application

Now that we've seen (albeit rather quickly) how we can use NHibernate, it is time to integrate it in the client application.
Because of the way NHibernate works when it has to save changed objects back to the DB, I'd like to use long living sessions.
When you retrieve an object from the database, NHibernate will keep this object in the Session. When you save the object back to the database, NHibernate will try to find the object in the ISession instance which is used to perform the save. If the instance is found, NHibernate will update the corresponding record. If the instance is not found, NHibernate will create a new record.
If you use a separate ISession to retrieve an object from the DB, and use another ISession to persist this object back to the DB, NHibernate will asume that it has to insert a new record.
Therefore, it is -imho- best to use the same ISession instance for retrieving and saving the same business object instance.
When you're using NHibernate in Windows applications, you can do this by using the 'long conversation' model.

In short, this means that you can keep your session open as long as the user is busy with a 'unit-of-work', but you can disconnect your session from the database when no database-access is needed for a while.

Although this article doesn't provide really in-depth information, I'd like to finish it here. This is yet another article which is way to long (maybe I should stop writing such long posts), but if you've gotten to here, please feel free to post any comments, critics, remarks, ...

woensdag 31 januari 2007

Meet My Mom

In the past few weeks, I've been making some portraits. Some of them in a studio, others 'on location'.
I will post some of the results here and I'll start with a portrait of my mother.

These photographs are shot in her 'study room'; my mom loves painting and calligraphy (she's pretty good at it) and I wanted to express this in my photographs.


high iso portrait creative mother
Just a pity that she's holding the pen a little bit to high


high iso portrait creative mother2

The photos have been taken with ambient light (I don't like to use flash for location-portraits). I've used a Nikon D200 with a 50mm f/1.8 lens mounted on it. Since there was not too much light available, I've choosen a small aparture number and a high ISO setting. (The EXIF information is available in the picture; you can easily view it using Opanda IEXIF Viewer"). Despite the high ISO setting, I've to admit that I'm pleasantly surprised with the noise levels in these photo's.

zaterdag 20 januari 2007

Lambda expressions in .NET

In C# 3.0, there will be a new feature available: lambda expressions. This new feature was necessary to create the LINQ feature, which will also be introduced in C# 3.0

Today, I came across an interesting article written by Howard Dierking in where he explains what lambda expressions are, and how you can use them.
Very nice and clear article.

Tagged

Seems that I've been tagged by Mike Nichols, so I'm supposed to come up with 5 things you don't know about me; here goes:


  • I've started playing music when I was about 8 or 9 years old. I've played guitar until I was about 16 years old. At that age, I stopped playing music. I didn't wan't to do it anymore. I was supposed to go to music classes each wednesday afternoon, and each saterday morning and I wanted to do other things during that time. :) Sometimes, I regret it though that I didn't continue with that guitar-thing. (I still have my guitar though, and maybe I'll pick it up again in the future)

  • I don't like cheese.
    Well, that's not completely true; I don't eat cheese 'as is', but I do like food that has cheese as an ingredient (pizza, croque monsieur, tiramissu, heck I even like cheese-burgers). I also like Cheetos. Weird huh?

  • I started programming relatively late. I was 17 years old when I wrote my first computer program.

  • I always wanted to become a pilot. Not on airliners, but a jet pilot. :) At age 16, I've sent a letter to the Belgian Air Force to enquire for more information about this. A few days later, I've received an information bundle about it. Unfortunately, I never took part in any of the 'promotions' of the Belgian Air Force. Maybe I was already realistic about my chances: there are only very few positions (about 4 each year) and numerous candidates.
    I haven't lost my interest in jets though; I still like to visit air-shows (although since a plane crashed at the Ostend Airshow in 1997, air-shows in Belgium aren't what they used to be...).
    If I would ever have the chance to be a passenger in a two-seater, I'd certainly do it!

  • I do like karting. Until a few years ago, I used to do it at least once a week. Unfortunately, I'm not able to keep up that frequency right now. I'm already happy if I can go karting once a month.
    I also dream of driving an open-wheel formula race car once (Formula One, Formula Ford, F3000, ... whatever

The 5 persons I'm tagging are: PJ van de Sande, Peter Veentjer, Jelle-Jan Van Veelen, Valentijn and Evan Hoff