« Previous post (Show Lists and Libraries)

So far in this series we have been covering the absolute basics of getting started. We will continue to do so but dig in a bit more in how to work with some of the standard list templates in SharePoint. I will cover the following list templates in the following turorials
- Links
- Tasks
- Announcements
- Contacts
- Calendar
Changes since last tutorial (Part 3)
Since we are stepping up a bit here and will introduce several new lists and more complexity I have moved around and refactored a bit in my project to create better separation. I did borrow some of the pattern from a normal MVC project
- Business, contains business layers and core functionality
- Content, where we will keep our NHibernate classes and mapping files
- Models, where we will keep our operational methods for NHibernate
All and all the project now looks like this

Strategy to get started working with a new type of list
The first thing you must decide is which fields to work with. Detailed field information can be acquired by using a tool like SharePoint Manager or the Camelot .NET Connector with Mini SQL Query. I will use the Mini SQL Query in this guides since it will allow us to test some queries and have a really good overview of the fields and their data.
The Links list
If you have connected to a Team-site this list will already be there (as can be seen in the previous tutorial). If the list is missing simply create it using the SharePoint interface. Also add a couple of links here for us to test with.

Download Mini SQL Query and open it on the same computer / server as where you have Camelot .NET Connector installed. Run the query
SELECT * FROM Links.all WHERE ContentType = 'Link'
This should render a result looking like this

If you look around a bit on the result we will find that the following fields are out of interest, ID, URLwMenu, Created, Modified, Comments. When running a query with those fields we will get a result looking something like this.

Simple enough, lets start to create some classes and mapping files
Content/Links.cs
This list seem simple but there is a small quirk in it. Note the format on the URL field (http://www.bendsoft.com, Bendsoft Website), one could think that the URL and Title should be stored in different fields but this is not the case, this is simply the way SharePoint stores URLs, this format is important to remember when inserting and updating data into URL fields in SharePoint.
We will ignore this small quirk for now but in the SDK this fields is replaced with a specialized URL property type that implements the IUserType interface.
Create the file Content/Links.cs and implement the following code
namespace NHibernateExample.Content
{
public class Links
{
public virtual int ID { get; protected set; }
public virtual string URL { get; set; }
public virtual System.DateTime Created { get; protected set; }
public virtual System.DateTime Modified { get; protected set; }
public virtual string Comments { get; set; }
}
}
Content/Links.hbm.xml
Create the file Content/Links.hbm.xml and enter the following mapping into it and remember to set the build action to “Embedded Resource”
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" auto-import="true">
<class name="NHibernateExample.Content.Links, NHibernateExample" lazy="true" table="Links">
<id name="ID">
<generator class="native" />
</id>
<property name="URL" />
<property name="Created" update="false" insert="false" generated="insert" />
<property name="Modified" update="false" insert="false" generated="insert" />
<property name="Comments" />
</class>
</hibernate-mapping>
The Created and Modified fields are managed by SharePoint, hence we must prevent NHibernate from trying to write any data to such fields.
Models/Links.cs
In the MVC pattern you use Models when communication with your datasources and this is exactly what we do here as well. This is nothing else then a pattern in our scenario but it is recommended to separate classes and communication when doing ORM applications.
We will use this file for our CRUD (Create Read Update Delete) methods. Create the file Models/Links.cs and paste the following code into it
using NHibernate;
using System;
using System.Collections.Generic;
using System.Linq;
namespace NHibernateExample.Models
{
/// <summary>
/// The Model class of links
/// Basic CRUD support is implemented
/// </summary>
public class Links
{
/// <summary>
/// Get all data from the links list
/// </summary>
/// <param name="session"></param>
public static void Read(ISession session)
{
IQuery query = session.CreateQuery("FROM Links");
IList<Content.Links> results = query.List<Content.Links>();
if (results.Any())
{
Console.WindowWidth = 90;
const string header = "{0, -9} {1}";
foreach (Content.Links item in results)
{
Console.WriteLine(header, "ID", item.ID);
Console.WriteLine(header, "URL", item.URL);
Console.WriteLine(header, "Created", item.Created.ToShortDateString());
Console.WriteLine(header, "Modified", item.Modified.ToShortDateString());
Console.WriteLine(header, "Comments", item.Comments);
Console.WriteLine(new string('-', 20));
}
}
else
{
Console.WriteLine("Could not fetch any lists");
}
}
/// <summary>
/// Get a single entry from the links list
/// </summary>
/// <param name="session"></param>
/// <param name="itemId"></param>
/// <returns></returns>
public static Content.Links Read(ISession session, int itemId)
{
IQuery query = session.CreateQuery("FROM Links WHERE ID = :ID").SetParameter("ID", itemId);
return query.UniqueResult<Content.Links>();
}
/// <summary>
/// Insert new post in the links list
/// </summary>
/// <param name="session"></param>
/// <param name="item"></param>
/// <returns>The created object</returns>
public static Content.Links Create(ISession session, Content.Links item)
{
using (ITransaction transaction = session.BeginTransaction())
{
var ret = session.Save(item);
transaction.Commit();
}
Console.WriteLine("Saved link to SharePoint with ID {0}", item.ID);
Console.WriteLine(new string('-', 20));
return item;
}
/// <summary>
/// Update a post in the links list
/// </summary>
/// <param name="session"></param>
/// <param name="item"></param>
/// <returns>The updated object</returns>
public static Content.Links Update(ISession session, Content.Links item)
{
using (ITransaction transaction = session.BeginTransaction())
{
session.Update(item);
transaction.Commit();
}
Console.WriteLine("Updated link with ID {0}", item.ID);
Console.WriteLine(new string('-', 20));
return item;
}
public static void Delete(ISession session, Content.Links item)
{
using (ITransaction transaction = session.BeginTransaction())
{
session.Delete(item);
transaction.Commit();
}
Console.WriteLine("Deleted link with ID {0}", item.ID);
Console.WriteLine(new string('-', 20));
}
}
}
That’s pretty much all the coding we need to do. Lets test!
Testing
Use your Main method in the program.cs file and run the code
using (ISession session = SessionFactory.OpenSession())
{
Models.Links.Read(session);
}

If you didn’t insert any data begin by doing so, the following snippet will insert a new link and read all available when done
using (ISession session = SessionFactory.OpenSession())
{
Links link = new Links()
{
URL = "http://blog.bendsoft.com, Bendsoft Official Blog",
Comments = "Attempt to insert data using NHibernate"
};
// Insert
var newLink = Models.Links.Create(session, link);
// Read
Models.Links.Read(session);
}

How to use the other methods will speak for it self. Comment this post if this needs clarification!
« Previous post (Show Lists and Libraries)