I’m slowly becoming intrigued by NHibernate and was playing around with it against AdventureWorks tonight.
I came up with this basic 2 table tutorial using Employee and Contact.
First, I created a wpf project for my user interface and I slapped a ListView on the main window like this:
<Window x:Class="NHAdventureWorks.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Window1" Height="300" Width="300" Loaded="Window_Loaded"> <Grid>
<ListView x:Name="lvwEmployees">
</ListView>
</Grid>
</Window>
Then I hooked up the Loaded Event:
private void Window_Loaded(object sender, RoutedEventArgs e)
{
this.lvwEmployees.ItemsSource = LoadEmployeesFromDatabase();
}
Then I added this code from the ‘hello world’ example in Manning’s “NHibernate in action” book:
static ISession OpenSession()
{
if (factory == null)
{
Configuration c = new Configuration();
//c.AddClass(typeof(Employee)); c.AddAssembly(Assembly.GetCallingAssembly());
factory = c.BuildSessionFactory();
}
return factory.OpenSession();
}
static ISessionFactory factory;
static IList<Employee> LoadEmployeesFromDatabase()
{
using (ISession session = OpenSession())
{
IQuery query = session.CreateQuery(
"from Employee as emp order by emp.Contact.LastName asc");
IList<Employee> foundEmployees = query.List<Employee>();
return foundEmployees;
}
}
Then I declared my domain model classes Employee and Contact as such:
internal class Employee {
internal int EmployeeId;
internal string LoginId;
internal Contact Contact { get; set; }
internal int ContactId;
public override string ToString()
{
return string.Format("{0} : {1} {2}", LoginId, Contact.FirstName, Contact.LastName);
}
}
internal class Contact {
internal int ContactId;
internal string FirstName;
internal string LastName;
}
Then I had to do the NHibernate specific stuff. First I added an xml file to the project called Employee.hbm.xml and then changed it’s build action to “Embedded Resource” (VERY IMPORTANT)
Then I added a Contact.hbm.xml file as well (also marked as Embedded Resource). Then their contents looked like this respectively:
<?xml version="1.0"?> <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
auto-import="true"> <class name="NHAdventureWorks.Employee, NHAdventureWorks"
table="HumanResources.Employee" lazy="false"> <id name="EmployeeId"
column="EmployeeID"
access="field"> <generator class="native" /> </id>
<property name="LoginId" access="field" column="LoginID"/> <many-to-one
name="Contact"
column="ContactID"
class="NHAdventureWorks.Contact, NHAdventureWorks"
not-null="true" /> </class>
</hibernate-mapping>
<?xml version="1.0"?> <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
auto-import="true"> <class name="NHAdventureWorks.Contact, NHAdventureWorks"
table="Person.Contact"
lazy="false"> <id name="ContactId"
column="ContactID"
access="field"> <generator class="native" /> </id>
<property name="FirstName" access="field" column="FirstName"/> <property name="LastName" access="field" column="LastName"/> </class>
</hibernate-mapping>
Of course there are some app.config settings that had to be put into place:
<?xml version="1.0" encoding="utf-8" ?> <configuration>
<configSections>
<section name="hibernate-configuration"
type="NHibernate.Cfg.ConfigurationSectionHandler, NHibernate" /> <section name="log4net"
type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" /> </configSections>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2"> <session-factory>
<property name="connection.provider"> NHibernate.Connection.DriverConnectionProvider
</property>
<property name="connection.driver_class"> NHibernate.Driver.SqlClientDriver
</property>
<property name="connection.connection_string"> Server=(local);database=AdventureWorks;Integrated Security=SSPI;
</property>
<property name="dialect"> NHibernate.Dialect.MsSql2000Dialect
</property>
<property name="show_sql"> false
</property>
<property name='proxyfactory.factory_class'>NHibernate.ByteCode.LinFu.ProxyFactoryFactory, NHibernate.ByteCode.LinFu</property> </session-factory>
</hibernate-configuration>
<log4net>
<appender name="ConsoleAppender"
type="log4net.Appender.ConsoleAppender, log4net"> <layout type="log4net.Layout.PatternLayout, log4net"> <param name="ConversionPattern" value="%m" /> </layout>
</appender>
<root>
<priority value="WARN" /> <appender-ref ref="ConsoleAppender" /> </root>
</log4net>
</configuration>